What is a fast PWM?
The fast PWM is a colloquial name given to an Arduino-based technique used to increase the frequency of the Pulse Width Modulator (PWM). This PWM frequency is changed from the default frequency of approximately 490 Hz to an arbitrary, often higher frequency.
This engineering brief demonstrates how to apply the fast PWM technique to the new Arduino UNO R4 Minima and the UNO R4 WiFi. The featured code unlocks hardware peripherals suitable for a range of applications including a 50 Hz RC servo, all the way to motor drives operating in the kHz range.
Note: This document describes the limitations of the pwm.h API. There may be more elegant solutions using the Renesas Flexible Software Package (FSP). Give the two solutions, the pwh.h is considerably easier to use. Stay tuned for an update to this page.
Tech Tip: This article departs from the programmer-friendly Arduino Application Programming Interface (API) such as the analogWrite( ) function with a deep dive into the underlying hardware and software. If you are pressed for time scroll down to find the Listing 1 software for the Arduino R4 WiFi with fast PWM on ports D3, D5, D6, D9, D10, and D11. Recall that these select pins are the default Arduino UNO PWM as indicated by the tilde symbol as shown in Figure 1 e.g., ~3.
Figure 1: Side-by-side comparison of the Arduino R4 Minima (left) and the Arduino R4 WiFi (right). The WiFi transceiver and the 12x8 LED matrix can be seen on the Arduino R4 WiFi.
Tech Tip: If you are new to Arduino and PWM techniques, please refer to this Arduino article that provides a solid introduction to the PWM and explore the Fast PWM technique applicable to the older ATmega328p line of microcontrollers.
What are the Arduino UNO R4 Minima and R4 WiFi boards?
The Arduino R4 Minima and R4 WiFi as shown in Figure 1 are the latest editions to Arduino’s classic line of microcontrollers. They are physically compatible with many of the shields originally designed over the last 15 years. The Arduino R4 WiFi includes an additional wireless WiFi module and an on-board 12x8 LED matrix. Both Arduino R4 modules share the Renesas R7FA4M1AB3CFM#AA0 32-bit CORTEX M4 microcontroller in a 64LQFP package. Note that the Arduino Professional Portenta C33 uses a related but more powerful Renesas Cortex M33 microcontroller. This is important as the PWM discussion in this engineering brief is closely related to the C33 PWM operation.
Tech Tip: Be especially careful to match the microcontroller and peripheral I/O pin voltage. They come in two flavors including 5.0 VDC and 3.3 VDC devices. These voltages are generally incompatible. A mismatch could damage your shield or microcontroller.
Fast PWM introduction
To their credit, Arduino has maintained backward compatibility for their classic line of ATmega328p-based UNO microcontrollers. The Arduino software abstraction layer (Arduino API) provides the familiar look and feel. The hardware remains compatible, including a 5 VDC interface. This is a wonderful feature, as code originally written 15 years ago will run on the new UNO R4 devices.
At the same time, the new R4 devices are orders of magnitude more complex with performance that would have been unobtainable at the low cost even a decade ago. The original 8-bit microcontroller is overshadowed by the new 32-bit Arm Cortex-M4 core with a Floating-Point Unit (FPU). This processing power is accompanied by equally impressive hardware-based peripherals.
The problem is that much of this power is locked up in the familiar and easy to use Arduino API. For example, the default PWM for the R4 is 490 Hz which is close to the original UNO with its 1 kHz PWM signal. The default 8-bit PWM is still activated using the analogWrite( ) function with available PWM signals on pins D2, D5, D6, D19, D10, and D11.
Previous solution to enhance PWM performance
In the past, the UNO programmer was able to increase PWM performance using so-called “fast PWM” operation. These routines were not part of the Arduino API, rather they required direct manipulation of the ATmega328p Special Function Registers (SFR). Stated another way, the code was not “Arduino portable,” as it relied on a specific microcontroller. For example, the Arduino Nano Every with its ATmega4809 microcontroller is close, but not compatible with the older Atmega328p. Consequently, the ATmega328p fast PWM routines are not functional requiring a workaround as described here. The remainder of this article is dedicated to finding similar, albeit more elegant, workaround to improve the PWM performance of the Arduino UNO R4.
PWM hardware resources for the Arduino UNO R4 Minima and WiFi
The Renesas R7FA4M1AB3CFM#AA0 microcontroller featured on the Arduino R4 Minima and WiFi is a powerful general-purpose microcontroller. It included provisions for controlling a Brushless DC Motor (BLDC). Consequently, it includes high performance PWM peripherals. In total, it features eight General PWM Timers (GPT), two of which are 32-bit devices while the remainder are 16-bit devices.
There are multiple ways to describe a microcontroller’s I/O pins including a signal name such as GTIOC0A, a port name such as P107, or a physical pin such as #41 associated with a LFQP94 package. The first two methods are shown in Figure 2 matrix, while the physical pin number is translated into an Arduino port name. Note that a given signal may be associated with select ports. The programmer is responsible for associating a given signal with a physical port. Stated another way, nearly every pin is associated with a multiplexer (MUX), the programmer must command the MUX by programming the associated SFR.
While the programmer is free to choose where to send the PWM signals, they are constrained by the PCB wiring of the Arduino R4 Minima and WiFi. This is reflected in Figure 2 which shows the microcontroller to Arduino I/O connections. As an example, the yellow highlighted sections for the Arduino R4 WiFi show the mapping required for hardware PWM on the default D2, D5, D6, D9, D10, and D11 PWM outputs. Code for this configuration is included as Listing 1.
It is important to recognize that the Renesas R7FA4M1AB3CFM#AA0 is limited to eight hardware PWMs. These are shown in Figure 2 as GPT0 to GPT7. Internally, the output of each PWM timer may be sent to the GTIOCXA or GTIOCXB network. These signals may then be associated with two physical microcontroller ports. These pins may or may be accessible on the Arduino UNO R4 PCBs.
This is best represented by the GPT1 resource on the Arduino R4 Minima. Internal to the microcontroller the PWM may be sent to GTIOC1A or GTIOC1B. This, in turn, may be sent to P105/P109 or P104/P110 respectively. The Arduino programmer will then assign the GPT1 resource to D2, D11, D3, or D12. Other resources such as GTIOC7A may be assigned to Arduino D8 or D9. In all cases, the hardware-based PWM is sent to one and only one location. Some signals such as GPT6 are not readily available to the Arduino user.
**Figure 2: This matrix shows the fast PWM option for the Arduino UNO R4 WiFi and UNO Minima. The highlighted section for the Arduino UNO R4 WiFi is reflected in the code listing featured in this article.
Tech Tip: PCB layout is an art. There are many competing requirements especially when designing a general-purpose development board such as the Arduino R4. This is reflected in Figure 2 which maps the GPT PWM timers to the Arduino Physical I/O (e.g., D3). Recall that each microcontroller signal may be routed to two different I/O pins. For example, GTIOC1A may be routed to P105 of P109. Both pins are available for the Minima as D2 or D11 while only one is available for the WiFi as pin D3.
On a related note, there is no guarantee that activating a hardware PWM will not interfere with other Arduino functionality. Careful troubleshooting is required for your design.
Tech Tip: Attempts to assign a GPT resource to multiple pins or to inappropriate pins will result in a run time error. The microcontroller will either ignore the request or enter a “Fault on interrupt or bare metal(no OS) environment.”
How to use the fast PWM on the Arduino UNO R4
Remember that an API is used to simplify or abstract away the underlying complexity. The Arduino language itself is an excellent example of an API that has allowed a generation of students and artists to leverage the power of the microcontroller. We will turn to another API to unlock the fast PWM for the Arduino Uno R4.
The API is defined within the pwm.h and pwm.cpp files which are located deep within the Arduino15 files stored on your PC. For a Windows machine, they are located at:
C:\Users\user_name\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.2.0\cores\arduino
C++ solution
This is a C++ solution that requires us to first instantiate a PWM object based on the desired Arduino pin assignment.
The first step is to include the required file and then instantiate a PWM object:
#include “pwm.h”
PwmOut objPWMD3(PWM_D3_PIN);
We then initialize the object to the desired frequency and duty cycle:
objPWMD3.begin(25000.0f, 0.0f);
We can then change the PWM duty cycle using the pulse_perc method:
objPWMD3.pulse_perc(D_perc);
These ideas are captured in Listing 1 used to configure ports D3, D5, D6, D9, D10, and D11 for the Arduino UNO R4 WiFi. Note that the code will not operate, as written, in the Minima as the pin assignments are different. Refer to Figure 2 and then adjust accordingly. Note that the Minima is incapable of simultaneous fast PWM operation on both pins D3 and D11.
/******************************************************************
* This code is applicable to the Arduino UNO R4 WiFi.
*
* **** It WILL NOT work in the Arduino UNO R4 Minima! ****
*
* Refer to the Figure 2 pin assignment to modify for use in the Minima.
/*****************************************************************/
#include "pwm.h"
#define PWM_D3_PIN D3
#define PWM_D5_PIN D5
#define PWM_D6_PIN D6
#define PWM_D9_PIN D9
#define PWM_D10_PIN D10
#define PWM_D11_PIN D11
PwmOut objPWMD3(PWM_D3_PIN); // Instantiate the PWM objects
PwmOut objPWMD5(PWM_D5_PIN);
PwmOut objPWMD6(PWM_D6_PIN);
PwmOut objPWMD9(PWM_D9_PIN);
PwmOut objPWMD10(PWM_D10_PIN);
PwmOut objPWMD11(PWM_D11_PIN);
void setup() {
Serial.begin(115200);
pinMode(PWM_D3_PIN, OUTPUT); // Configure the PWM I/O pin
pinMode(PWM_D5_PIN, OUTPUT);
pinMode(PWM_D6_PIN, OUTPUT);
pinMode(PWM_D9_PIN, OUTPUT);
pinMode(PWM_D10_PIN, OUTPUT);
pinMode(PWM_D11_PIN, OUTPUT);
objPWMD3.begin(25000.0f, 0.0f); // Instantiate the PWM objects with a
// frequency of 25 kHz and a 0% duty cycle
objPWMD5.begin(25000.0f, 0.0f);
objPWMD6.begin(25000.0f, 0.0f);
objPWMD9.begin(25000.0f, 0.0f);
objPWMD10.begin(25000.0f, 0.0f);
objPWMD11.begin(25000.0f, 0.0f);
}
void loop() { // Ramp between 0.0 and 100.0
static float D_perc = 0;
static bool state = 1;
if (state) {
D_perc += 0.1;
if (D_perc > 100) {
state = 0;
D_perc = 100;
}
} else {
D_perc -= 0.1;
if (D_perc < 0) {
state = 1;
D_perc = 0;
}
}
objPWMD3.pulse_perc(D_perc); // Set the duty cycle based on the ramp
objPWMD5.pulse_perc(D_perc);
objPWMD6.pulse_perc(D_perc);
objPWMD9.pulse_perc(D_perc);
objPWMD10.pulse_perc(D_perc);
objPWMD11.pulse_perc(D_perc);
Serial.println(D_perc);
delay(20);
}
Listing 1: Arduino UNO R4 WiFi specific code used to configure a fast PWM on pins D2, D5, D6, D9, D10, and D11
Results
The PWM operation was tested using the Digilent Analog Discovery as shown in Figure 3. In this example, the Discovery is used as a multi-channel logic analyzer.
The results are shown in Figure 4. In this example, the yellow highlighted Arduino Pins from Figure 2 are encoded into Listing 1. The result is six independent 25 kHz PWM signals operating on pins D2, D5, D6, D9, D10, and D11.
Figure 3: Testing the Arduino UNO R4 WIFI’s various PWM combinations using a Digilent Analog Discovery.
Figure 4: The Arduino UNO R4 WiFi is configured to produce 6 PWM signals on pins D3, D5, D6, D9, D10, and D11. In this example, each PWM has a frequency of 25 kHz.
Conclusion
The Arduino UNO R4 Minima and WiFi represent a significant step forward from the Arduino UNO R3. The new devices feature a powerful 32-bit Arm Cortex M4 process with equally impressive hardware peripherals including the GPT PWM timers featured in this article. The pwm.h API included in your computer’s Arduino15 folder is the key to unlocking the hardware capability. With proper attention to pin assignments, we can increase the versatility of the Arduino UNO R4 Minima and WiFi.
Be sure to expand your knowledge by answering the questions and critical thinking questions contained at the end of this note. Also, please let us know if you were able to successfully apply this technique in your projects.
Best wishes,
APDahlen
Helpful links
Please follow these links to related and useful information:
- Digikey’s product selection guides
- Arduino education content.
- UNO R4 Minima | Arduino Documentation
- UNO R4 WiFi | Arduino Documentation
- RA4M1 - 32-bit Microcontrollers with 48 MHz Arm Cortex-M4
About this 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 (partially interwoven with military experience). 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 educational articles about electronics and automation.
Highlighted experience
Dahlen is an active contributor to the DigiKey TechForum. At the time of this writing, he has created over 170 unique posts and provided an additional 570 forum posts. Dahlen shares his insights on a wide variety of topics including microcontrollers, FPGA programming in Verilog, and a large body of work on industrial controls.
A collection of Dahlen’s Arduino educational articles can be found at Arduino education content.
Questions
The following questions will help reinforce the content of the article.
-
What is the default PWM frequency for the Arduino UNO R4 Minima and WiFi? Also, what pins are PWM compatible.
-
What is the DigiKey cost difference between the Arduino UNO R4 Minima and the WiFi. Given this difference, why would you select one board over the other?
-
List at least three application that benefit from a fast PWM.
-
What is the benefit of increased bits associated with a PWM. For full credit, include a sketch to demonstrate your understanding of the underlying process.
-
The article uses the term “fast PWM” for alignment with previously written material. Does the term completely encapsulate the PWM capabilities. Hint: Can the R4 hardware PWMs be used to control a 50 Hz RC servo?
-
Explain the GPTX to GTIOCXY to PXXX to Arduino DX chain implied in the article.
-
What is an object? Have you used other objects in an Arduino environment? Hint Serial.
-
What is a method? Have you used other objects in an Arduino environment? Hint println.
-
Locate the pwm.h file from within the Arduino15 folder on your PC. Identify the methods associated with the hardware PWM.
-
Why is the Minima incapable of simultaneous fast PWM operation on both pins D3 and D11?
-
Why is Listing 1, as written, inappropriate for the Arduino Minima? How could it be changed?
-
Modify Listing 1 to match the PWM setup implied in Figure 3.
-
What is the significance of the obj prefix? Hint: Hungarian.
-
Figure 2 is constrained to the traditional Arduino I/0 pins. Locate the schematic for the Arduino UNO R4 Minima and WiFi and determine the PWM signal(s) available on the 6-pin ISCP connection.
-
Why is it important to initialize the PWM with a 0% duty cycle?
Critical thinking questions
These critical thinking questions expand the article’s content allowing you to develop a big picture understanding the material and its relationship to adjacent topics. They are often open ended, require research, and are best answered in essay form.
-
Contrast and compare the hardware with the software solutions for PWM operation. Hint: Sleep.
-
What are the trade-offs associated with PWM frequency for driving a brush DC motor.
-
Describe how to construct a variable DC output using a PWM signal. Describe the benefit of increased frequency and bit depth.
-
Speculate as to why the Arduino designers changed pin assignments between the Arduino UNO Minima and WiFi.
-
How many PWM signals are required to drive a BLDC motor. Hint: Analyze the signal names in the Renesas R7FA4M1AB3CFM#AA0 datasheet.
-
What is the name of the IDE typically associated with the Renesas R7FA4M1AB3CFM#AA0? Contrast and compare the IDE with the Arduino IDE.
-
The Renesas R7FA4M1AB3CFM#AA0 offers significant improvement over the original ATmega328p. However, the ATmega328p is a relatively old design. Contrast the Renesas R7FA4M1AB3CFM#AA0 with a modern 8-bit microcontroller such as the ATtiny1607. Hint: Horses for courses.
-
The Renesas R7FA4M1AB3CFM#AA0 contains two 32-bit hardware PWMs. Does the API solution described in this article take advantage of this hardware resource? If not, include the bare-metal code to configure and utilize the hardware.