Nodemcu PWM controlled DC motor

dc motor nodemcu interfacing

DC motors are widely used in various applications such as robotics, automation, and industrial control systems. One of the ways to control the speed of a DC motor is through Pulse Width Modulation (PWM). PWM is a technique used to vary the width of pulses applied to a DC motor, which in turn, controls the speed of the motor. In this blog post, we will be discussing how to control a DC motor using NodeMCU PWM.

What is NodeMCU?

NodeMCU is an open-source platform that is built on the ESP8266 microcontroller. It is an easy-to-use development board that allows you to connect to the internet, control devices, and read sensors. The NodeMCU board has a built-in wifi module, which makes it an ideal platform for IoT projects.

Controlling DC Motor using NodeMCU PWM

To control a DC motor using NodeMCU PWM, we will need to connect the motor to the NodeMCU board.

The NodeMCU board has a built-in PWM module that is responsible for generating Pulse Width Modulation signal that can be used to control the speed of the motor. The PWM module can be configured to generate pulses of varying widths, PWM signals, which in turn, controls the speed of the motor.  We can use any of its nine PWM pins to control motors, such as a DC motor. Because, NodeMCU is a WiFi capable microcontroller, a DC motor can be controlled using web interface over WiFi connection. 


To connect the Nodemcu to the web we can use Node-Red.

Node-RED is an open-source programming tool for wiring together hardware devices, APIs, and online services. It is built on Node.js and is designed to be simple and easy to use. Node-RED allows developers to create complex Internet of Things (IoT) applications using a visual interface.

Node-RED uses a drag-and-drop interface, which allows users to create complex flows by connecting together different nodes. Each node represents a different function, such as reading data from a sensor or sending data to a cloud service. The flows can be triggered by specific events or run continuously.

Node-RED has a wide range of built-in nodes for different protocols and services, such as MQTT, HTTP, and IoT platforms like IBM Watson IoT and AWS IoT. Additionally, users can create their own custom nodes or install additional nodes from the Node-RED community.

Node-RED is widely used in IoT and home automation projects, as well as in industrial automation and data processing. It is also useful in creating automations, integrations and workflows for various purposes. Node-RED is supported by a large community, with many tutorials, examples, and plugins available.

Overall, Node-RED is a powerful tool that allows developers to create complex IoT applications quickly and easily, using a visual interface and a wide range of built-in nodes and community-built nodes.

Here Node-Red is used configure to communicate with the Nodemcu using the MQTT protocol. For the MQTT protocol we will use the open source Mosquitto MQTT application. Thus this is another example of Internet of Things application using Node-Red.

Nodemcu and DC motor interfacing

The following shows the DC motor connected to the Nodemcu with the help of breadboard.

dc motor nodemcu interfacing

dc motor nodemcu interfacing

The following circuit diagram shows how to connect Nodemcu with the DC motor using BC547 transistor, 1N4004 protection diode and 100nF capacitor.

interfacing circuit diagram of nodemcu and dc motor

Notice that the nodemcu board is powered using 5V breadboard power supply while the DC motor is powered using 9V battery(or can also be powered with household power socket). For this the Vin pin and ground is connected to the breadboard power positive and negative rails. 

There are 9 PWM pins in NodeMCU module which is shown in the pin out diagram below.

Nodemcu PWM pins

Here the nodemcu pwm GPIO5(D1) pin is used to send PWM signal to control the speed of the DC motor. The PWM pin GPIO 5 or D1 is connected to the base of the BC547 NPN transistor via 1KOhm. One of the DC motor wire is connected to the positive side of the 9V and the other wire is connected to the collector of the BC547 transistor. A 100nF capacitor and a protection diode 1N4004 are connected from the +ve terminal of 9V to the collector. The emitter is connected to the ground of the battery. Also a LED is connected to the PWM pin GPIO 5 via 220Ohm which is used to indicate the PWM signal with brightness increase and decrease.

The following shows the web interface to control the DC motor designed with Node-Red.

By using the slider we can increase and decrease the PWM signal value, that is the duty cycle of the PWM(Pulse Width Modulation) signal. The higher the PWM value, the higher will be the duty cycle and faster will the DC motor spin. In this way the speed of the DC motor can be controlled using PWM signal.

Mosquitto MQTT broker application

The Mosquitto MQTT application can be download and installed from the following link.

Once downloaded, you should see the mosquitto.exe application in the extracted folder.

mosquitto server

You can start the mosquitto MQTT server(also called MQTT broker) using the following CLI command:

> mosquitto -v

Mosquitto MQTT broker

Once the MQTT broker is started the MQTT server will run on localhost( with port 1883.

NodeMCU Program

 In this tutorial, the program code is written in and uploaded using Arduino IDE. To write program for ESP8266 Nodemcu board we have to install ESP8266 Nodemcu libraries and for this see the tutorial LED Blink using ESP8266 & Arduino IDE. Once you have installed the library the IDE must be configured to use the NodeMCU board and configure the port which is as shown below.

The Nodemcu program code for DC motor control via red-node and wifi is below.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Enter your router credentials
const char* ssid = "your_router_ssid";
const char* password = "your_router_password";

// Enter your MQTT broker IP address
const char* mqtt_server = "";

// Initializes the espClient
WiFiClient espClient;
PubSubClient client(espClient);

// LED connected to ESP8862 NodeMCU GPIO5(D1)
const int pwmPin = 5;

// Function to connect ESP8266(NodeMCU) to the router
void wifiConfig(){
  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
  Serial.print("WiFi connected - ESP8266 client IP address: ");

void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Topic: ");
  Serial.print(". Message: ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
    messageTemp += (char)message[i];

  // If a message to subscribed is received send PWM signal on PWM pin and print message

// This functions reconnects your ESP8266 to your MQTT broker
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client")) {
      // Subscribe to a topic
    } else {
      Serial.print("failed, rc=");
      Serial.println(" try again in 5 seconds");

//the PWM pin is configured as output
//serial communication is activated
//the wifi connection is started
//the MQTT server is setup and started
//callback function to execute subscribe routine
void setup() {
  pinMode(pwmPin, OUTPUT);  
  client.setServer(mqtt_server, 1883);

//The connection is established, if disconnected
void loop() {

  if (!client.connected()) {

In the above code, we have used ESP8266WiFi and PubSubClient libraries. The ESP8266WiFi library is used to connect the nodemcu to the router over WiFi. The PubSubClient library is used to create a client which can then publish or subscribe over the WiFi network.

For WiFi connection we have to provide router SSID and password. Also we have to specify the MQTT broker/server IP address which when used on PC can be found using the ipconfig command.

The function wifiConfig() is used to create the wifi connection to the WiFi router. This function also prints out the IP address of the nodemcu. This is illustrated below. You will see this on the serial monitor after you upload the program code above.

Here the nodemcu is mqtt client and we are subscribing to topic motor/pwm. So for this PubSubClient library is required. First we create a client object called espClient. This then is used in various part of the program. For example, it is used in the reconnect() function which connects and tries re-connection continuously if the the connection is lost. It is also similarly used in the loop() function. The callback() function is where the pwm data from the web interface is received by the nodemcu client via WiFi. The message is stored temporarily in the messageTemp string. This message is converted to integer and then send to the PWM signal is sent using the analogWrite() function. 

Node Red Programming

The next step is write program flow in node-red. If you don't have already installed node-red then see the tutorial Node Red with Arduino Simple Example to learn how to install node red. The following is the node-red flow diagram for controlling DC motor using slider in node red using MQTT subscribe node.

The node labelled pwm is a slider node from the dashboard library, the node labelled PWM is a gauge node also from dashboard libary and the node labelled motor/pwm is a mqtt_out node from the network library. The dashboard library is not installed in new installation of node red so see the tutorial Node Red IoT with Arduino DHT11 for this. The mqtt nodes however are installed by default.

The dashboard nodes requires tab and group name. So first create a new tab and name it motor and then from new tab motor create a new group and name it pwm.

 Once the tab and group are created we can next configure the dashboard nodes. The configuration of the pwm slider node is shown below.

The configuration of the PWM gauge node is shown below.

And the configuration of the motor/pwm  mqtt_out node is below.

Once this is node flow is complete and the mqtt broker is running, press the Deploy button then the Start button.

After that go to the http://localhost:1880/ui and you should see the web interface for the DC speed control.

The node-red flow program is below.

        "id": "5368dda7df7be6f0",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
        "id": "bd922026d266afcd",
        "type": "mqtt out",
        "z": "5368dda7df7be6f0",
        "name": "",
        "topic": "motor/pwm",
        "qos": "1",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "56d8bb395649bc55",
        "x": 510,
        "y": 280,
        "wires": []
        "id": "036e1d78a74dbdcd",
        "type": "ui_slider",
        "z": "5368dda7df7be6f0",
        "name": "",
        "label": "pwm",
        "tooltip": "",
        "group": "6af2adfd5ce27e94",
        "order": 3,
        "width": 0,
        "height": 0,
        "passthru": true,
        "outs": "all",
        "topic": "motor/pwm",
        "topicType": "str",
        "min": 0,
        "max": "255",
        "step": 1,
        "className": "",
        "x": 270,
        "y": 280,
        "wires": [
        "id": "7cb04efb06736f16",
        "type": "ui_gauge",
        "z": "5368dda7df7be6f0",
        "name": "",
        "group": "6af2adfd5ce27e94",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "PWM",
        "label": "",
        "format": "{{value}}",
        "min": 0,
        "max": "255",
        "colors": [
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 490,
        "y": 200,
        "wires": []
        "id": "56d8bb395649bc55",
        "type": "mqtt-broker",
        "name": "",
        "broker": "localhost",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
        "id": "6af2adfd5ce27e94",
        "type": "ui_group",
        "name": "PWM",
        "tab": "1a1b68ef501148ad",
        "order": 1,
        "disp": false,
        "width": "5",
        "collapse": false,
        "className": ""
        "id": "1a1b68ef501148ad",
        "type": "ui_tab",
        "name": "Motor",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false

Video demonstration

The following video shows how the speed of the DC motor is controlled using Nodemcu PWM via WiFi.


In conclusion, controlling a DC motor using NodeMCU PWM is a simple and effective way to control the speed of a DC motor. The NodeMCU board is an easy-to-use platform that makes it easy to connect to the internet, control devices, and read sensors. With the built-in PWM module and NodeRed, it is easy to configure and control the speed of a DC motor.

It is worth mentioning that, in order to ensure the safety of your project and to avoid any damage to the motor and the board, you should always be aware of the current and voltage that the motor can handle and make sure to use a proper voltage regulator and protection circuit to prevent over current and over voltage.

Post a Comment

Previous Post Next Post