Advanced PWM Functionality with the Arduino PORTENTA Pro C33

What is the default PWM frequency for the Arduino PORTENTA Pro C33?

Arduino has a long history of maintaining backward compatibility between their products. The new Arduino PORTENTA Pro C33 is no exception. Like the Arduino Uno, the default Pulse Width Modulation (PWM) frequency for the C33 is approximately 490 Hz with an 8-bit resolution. Recall that the default PWM is accessed using the analogWrite( ) function.

This is a good starting position for many projects but is undesirable for advanced projects especially those involving motor control. The low frequency is audible and the PWM 8-bit resolution could be improved. This is especially true when we consider the capability of the C33, Renesas Arm Cortex processor. This device is capable of much greater performance beyond the default settings and the limitations of the familiar analogWrite( ) function.

This engineering brief identifies a method to unlock the C33’s PWM. It provides the ability to set the PWM frequency to an arbitrary value with the ability to use fractional (type float) values for the duty cycle. The best part is that the code is already installed as part of the Arduino IDE. Figure 1 shows the hardware used in the setup.

Figure 1: The PWM for the Arduino PORTENTA Pro C33 may be set to an arbitrary frequency with duty cycle set as a floating-point percentage.

Where is this PWM code for the PORTENTA Pro C33 located?

To locate the PWM code we need to explore the inner working of the Arduino IDE. As a starting point, we all know that a specific Arduino microcontroller must be identified before we are able to compile (verify) the program. This is important as it directs the IDE to compile the program for the selected microcontroller. The classic blinky program is a perfect example. The high-level Arduino code is the same for all Arduino family members while the compiled machine code is very different for, say a Microchip ATmega (formerly Atmel), and a Renesas Arm.

When you select your desired Arduino board, the IDE is directed to use the associated hardware-specific set of files. On a Windows machine, the PWM files for the C33 are named pwm.h and pwm.cpp. They are located at:

C:\Users\your_name\AppData\Local\Arduino15\packages\arduino\hardware\renesas_portenta\1.1.0

There are additional levels of complexity associated with this IDE process. However, this oversimplified introduction is sufficient for our discussion.

How can I change the PWM frequency and bit width for the PORTENTA Pro C33?

The process is relatively simple; all we need to do is leverage the prebuilt PwmOut class that is included in the pwm.cpp and pwm.h pair. As seen in the code listing below, we start the process by including the pwm.h file. The next step is to instantiate an instance of PwmOut. In this code listing, we call the instance myPWM. Note that we instantiate myPWM by associating it with a specific I/O pin – D6 in this example. The last step is to activate your instance of the PWM using myPWM.begin( );. With no other actions, the PWM will run at the default 490 Hz with a 50% duty cycle.

As you explore the pwm.h and pwm.cpp files you will see that a variety of methods are included to configure and adjust the PWM. In this example, we set the PWM to operate at 25 kHz using the statement myPWM.period_us(40);. Finally, we adjust the duty cycle using the statement myPWM.pulse_perc(D_perc);. Note that the duty cycle percentage (D_perc) is a type float allowing fine control of the PWM duty cycle. In this demo the PWM slowly transitions from 0% to 100% duty cycle and then slowly back again as shown in Video 1.

#include "pwm.h"
#define PWM_PIN D6

PwmOut myPWM(PWM_PIN);  // constructor associating the PWM with a particular pin

void setup() {
  pinMode(PWM_PIN, OUTPUT);
  Serial.begin(9600);
  myPWM.begin();
  myPWM.period_us(40);
}

void loop() {
  static float D_perc = 0;
  static bool state = 1;
  if (state) {
    D_perc += 0.25;
    if (D_perc > 100){
      state = 0;
      D_perc = 100;
    }
  } else {
    D_perc -= 0.25;
    if (D_perc < 0){
      state = 1;
      D_perc = 0;
    }
  }

  myPWM.pulse_perc(D_perc);
  Serial.println(D_perc);
  delay(100);
}

Results using the demo code

The results for the demo program are included as Video 1. Here we see a screen capture from the Digilent Analog Discover along with the serial monitor data from the Arduino IDE. The 25 kHz signal (40 us) appears rock steady. The duty cycle is seen to smoothly transition between with a 0.25% change per step.

Video 1: The Arduino PORTENTA Pro C33 is seen to produce a 25 kHz PWM with a smoothly changing PWM in 0.25% increments.

Parting thoughts

This is certainly not an optimized solution. However, the implementation was relatively easy, and the results are expected to be excellent for a future article involving servo motor control. Also, the fact that the duty cycle control is expressed as a floating-point percentage will help from an educational standpoint.

I leave it to you to simplify and modify the code to suit your needs. Kindly include tips and suggestions. Better yet, please share your experiences using this enhanced PWM technique in your projects.

Best Wishes,

APDahlen

Please follow this link for related Arduino education content.

About the Author

Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians. Dahlen has returned to his Northern Minnesota home and thoroughly enjoys researching and writing articles such as this. LinkedIn | Aaron Dahlen - Application Engineer - DigiKey

1 Like