Additional Information

Site Information

 Loading... Please wait...


ESP32 DC Motor PWM Speed Control (Pulse Width Modulation) - The Hidden Facts

Posted by Wilfried Voss on

Lately, I have worked on two projects requiring DC motor control per PWM (Pulse Width Modulation). What both projects had in common was a profound lack of documentation regarding PWM control, specifically the side effects that have a significant impact on the programming. 

This post aims to point to these quirks that may cause considerable headaches during the software development phase. In the first case, the task was to control a Thomson Eletrak Linear Actuator per Arduino Due. Based on my experience, I have written several posts addressing the learning curve and conclusions. These posts are: 

Luckily, my experience with the linear actuator control helped me to avoid similar delays with the second project, which required controlling up to four DC motors per CAN Bus, specifically SAE J1939. Here, I chose the ESP32 processor, which represents my first choice when it comes to development and prototyping.

To mention it upfront, programming PWM-based motor control using either the Arduino series of processors or the ESP32 is ridiculously easy. Also, I will not needlessly repeat information on PWM basics and the actual programming. These topics have been documented to a great degree, and I have listed references below. I used the same references successfully for my ESP32 project. However, as I mentioned previously, there are some quirks that have not been sufficiently explained in any of the examples I found online.

The Problem: The general perception is that you can easily control a DC motor anywhere between zero and maximum speed. That is, however, not the case. 

Note: In the past, I have been involved with programming motion controllers, but I am far from being a motion control expert. Any experienced motion control engineer may cringe, given my observations and conclusions. Nevertheless, my projects work. If you feel compelled to add a comment, please feel free to contact me (constructive contribution or criticism is appreciated). 

The problem is with the minimum speed, i.e., the DC motor cannot move below a certain minimum PWM duty cycle. 

I found a few comments, addressing this effect, in the posts listed below: 

For the [PWM] frequency we’re using, when you apply duty cycles smaller than 200, the motor won’t move and will make a weird buzz sound. So, that’s why we set a duty cycle of 200 at the start. 
Reference: ESP32with DC Motor - Control Speed and Direction | Random Nerd Tutorials...

Suppose the duty is zero, motor does not run and when duty cycle is 100 % the motor moves on maximum RPM. But this concept is not always right because motor starts running after giving some fixed voltage that is called threshold voltage.
Reference: DCMotor Speed Control Using Arduino & PWM - (

According to the Thomson Electrak user manual (obviously the most professional explanation), the "PWM driver will not provide enough voltage for the motor to operate properly under 20% utilization, therefore 20% should be considered a lower limit for speed control."

However, even this last explanation does not address the full extent of the limitations involved. There is a second speed limit, somewhat higher than the minimum speed, at which the motor can run but cannot start when this speed is applied at motion start.The effect is the above-mentioned "buzzing," meaning the motor does not move.

According to the above-referenced comments, I call this the "threshold speed" (again, correct me if necessary). In the case of the linear actuator, the threshold speed also depends on the gear's condition, i.e., older gears require a higher threshold speed due to mechanical wear.

Note: The exact definition of minimum and threshold duty cycle differs from motor to motor. In my test setup, I played with the duty cycle settings to determine the limits.

Regarding the programming, you need to consider the following:

  1. When the required duty cycle (speed) is at or below the minimum speed, you need to stop the motor.
  2. When you need to start the motor at a speed between minimum and threshold speed, you need to apply a velocity higher than threshold for a short time, then continue with the initially required speed.

Item 2 is demonstrated in the programming sample found at  DC Motor Speed Control Using Arduino & PWM - (

analogWrite(out1, 255);    // Apply max. speed
delay(10);                          // Wait for 10 msec
analogWrite(out1, 175);    // Apply desired speed

This sample refers to an Arduino processor, but the basic algorithm is the same for the ESP32.


Electronics Projects with the ESP8266 and ESP32: Building Web Pages, Applications, and WiFi Enabled DevicesElectronics Projects with the ESP8266 and ESP32: Building Web Pages, Applications, and WiFi Enabled Devices

Copperhill Technologies highly recommends using this book for your wireless application projects. Yes, many good books and free online resources are available these days, but this is the book we are using. It made our approach to Bluetooth, BLE, and WIFI a breeze. Programming wireless applications without hassles was fun, and we will share them on this web page.

Projects throughout the book utilize the wireless functionality and processing power of the ESP microcontrollers. Projects are built in the Arduino IDE, so you don't need to download other programming software. In addition, mobile apps are now ubiquitous, making the app build projects of the book very relevant, as are the web page design projects.

In Electronics Projects with the ESP8266 and ESP32, you'll see how easy and practical it is to access information over the internet, develop web pages, build mobile apps to remotely control devices with speech recognition, or incorporate Google Maps in a GPS route tracking app. More Information...

ESP32 Project: USB to Bluetooth Gateway

The ESP32 processor allows the integration of Wi-Fi, Bluetooth, and Bluetooth LE (BLE) for a wide range of IoT (Internet of Things) applications. Using Wi-Fi ensures connectivity within a large radius. At the same time, Bluetooth allows the user to easily detect (with low-energy beacons) a module and connect it to an Android/iOS smartphone or [...]

Read More »

Arduino-Compatible Microsoft Azure Certified IoT Development Kit with Visual Studio Code Support

This Microsoft Azure Certified IoT DevKit (IOT-AZ3166) is an all-in-one kit optimized for prototyping and developing Internet of Things (IoT) applications leveraging Microsoft Azure services. It supplies an Arduino-compatible board with multiple peripherals such as an OLED display, sensors, hardware debugging chip (ST-Link), and security chip. The project collection offers creative examples for learning and reference, plus [...]

Read More »

Arduino Portenta H7 - Dual-Core STM32 Processor Board with Two CAN FD Ports and Support for Arduino IoT Cloud

The Portenta H7's central processor is represented by the dual-core STM32H747, including a Cortex M7 at 480 MHz and a Cortex M4 at 240 MHz. The two cores intercommunicate through a Remote Procedure Call mechanism that seamlessly enables calling functions on the other processor. Both processors share on-chip peripherals and can run Arduino Sketches on the Arm [...]

Read More »

Four Channel CAN Bus to USB Gateway Using The Arduino Due

In the past, I frequently received inquiries regarding the availability of a four-channel CAN Bus gateway. Such devices exist in the marketplace; however, they are usually costly, and, after all, they don't support easy customization or programming. While we at Copperhill Technologies have the ability to create such a gateway, this is primarily a matter [...]

Read More »

SAE J1939 250k/500k Baudrate Converter Using Arduino Due With Dual CAN Bus Port

In the past months, customers have approached me regarding a CAN Bus baud rate converter for SAE J1939 networks. The original SAE J1939 Standards Collection was limited to a baud rate of 250k, basically to keep things simple and reliable. I don't know what triggered the decision to add the additional 500k baud rate. From [...]

Read More »

ESP32 Development Boards and Accessories for IoT Applications

The integration of Wi-Fi, Bluetooth, and Bluetooth LE allows a wide range of applications with the ESP32 modules. Using Wi-Fi ensures connectivity within a large radius, while using Bluetooth allows the user to easily detect (with low-energy beacons) a module and connect it to a smartphone. The chips add priceless functionality and versatility to your [...]

Read More »

CAN Bus Shield for Arduino, Mbed Platform With Fault-Tolerant MAX33040E CAN Transceiver

The MAX33040Eshld shield evaluation kit by maxim integrated represents a demonstration and development platform for the MAX33040E CAN Bus transceiver. It serves as a standalone evaluation board and the Mbed or Arduino platform to communicate with a CAN Bus network. The board features test points to access critical signal pins of the transceiver. The MAX14931 digital isolator [...]

Read More »

STM32 Ultra-Low-Power IoT Development Kit With Integrated CAN FD Interface

Rutronik introduced its development kit RUTDevKit-STM32L5 for AI-based (Artificial Intelligence) applications at the edge. The kit also comes with a CAN FD interface.The kit utilizes the 110-MHz STM32L562ZET6Q micro-controller. The 32-bit Arm Cortex-M33 processor with Arm Trustzone function offers hardware-based security features. The core implements a protected processing environment for cyber protection and sensitive code and an [...]

Read More »

Sensor Networks with XBee, Raspberry Pi, and Arduino: Sensing the World with Python and MicroPython

This book explains how to build sensor networks with Python and MicroPython using XBee radio modules, Raspberry Pi, and Arduino boards. This revised and updated edition will put all of these technologies together to form a sensor network and show you how to turn your Raspberry Pi into a MySQL database server to save sensor data. The reader [...]

Read More »