Unit 4: Programming NodeMCU for PWM
I. PWM Orientation
Pulse-width modulation (PWM) is a technique for controlling the average power delivered to a load by switching a digital signal rapidly between HIGH and LOW states. On NodeMCU, which commonly uses the ESP8266, PWM is generated in software through the Arduino programming environment. The load responds to the average effect of the pulses: an LED appears dimmer or brighter, a servo interprets pulse width as position, and a motor receives adjustable average voltage through a driver.
-
Duty cycle: The percentage of one PWM period for which the signal remains HIGH.
[
D=\frac{T_{\text{ON}}}{T}\times100
]Here, (D) is duty cycle, (T_{\text{ON}}) is HIGH time, and (T) is the complete period.
-
Frequency: The number of PWM cycles per second, measured in hertz (Hz).
[
f=\frac{1}{T}
]For example, a 1 kHz signal has a period of 1 ms.
-
Average output: For a rapidly switched signal, the approximate average voltage is:
[
V{\text{AVG}}\approx D\times V{\text{SUPPLY}}
]A 50% duty cycle applied to a 3.3 V logic-level signal has an average value of approximately 1.65 V.
-
NodeMCU PWM range: In the ESP8266 Arduino core,
analogWrite()generally uses values from 0 to 1023. A value of0produces 0% duty cycle, while1023produces approximately 100%. -
Logic-level limitation: NodeMCU GPIO pins output approximately 3.3 V and cannot directly supply large current. LEDs require a current-limiting resistor, and motors require a transistor or motor-driver circuit.
-
GPIO conventions: GPIO numbers and board labels are different. For example, NodeMCU label
D1commonly corresponds to GPIO5. Programs should use the board label when the selected board package supports it, or use the correct GPIO number explicitly. -
Electrical reference: All connected control circuits should share a common ground unless an isolating interface is intentionally used.
II. Controlling the Brightness of LED
A. Purpose and Principle
LED brightness is controlled by varying the duty cycle of a PWM signal applied to the LED circuit. The LED switches too quickly for the human eye to distinguish individual pulses, so its perceived brightness follows the average current.
B. Controlling the brightness of led
This technique connects an LED to a PWM-capable NodeMCU pin through a resistor and changes the analogWrite() value.
-
Circuit connection: Connect the LED anode to a PWM GPIO through a resistor, connect the cathode to GND, and place the resistor in series.
- Resistor purpose: A typical value such as (220\ \Omega) or (330\ \Omega) limits current.
- Current calculation: With a 3.3 V supply, a red LED forward voltage of approximately 2.0 V, and a (330\ \Omega) resistor:
[
I=\frac{3.3-2.0}{330}\approx3.9\text{ mA}
]- Polarity: The longer LED lead is normally the anode; the shorter lead and flat edge generally identify the cathode.
-
PWM mapping: The value
xinanalogWrite(pin, x)determines duty cycle.[
D\approx\frac{x}{1023}\times100
]A value of
512gives approximately 50% duty cycle. -
Basic program: This program gradually increases and decreases LED brightness.
const int ledPin = D1; // ledPin identifies the LED output pin
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
for (int level = 0; level <= 1023; level += 8) {
analogWrite(ledPin, level);
delay(10);
}
for (int level = 1023; level >= 0; level -= 8) {
analogWrite(ledPin, level);
delay(10);
}
}-
Symbol definitions:
ledPinis the GPIO connected to the LED,levelis the PWM command from 0 to 1023, anddelay(10)pauses for 10 milliseconds. -
Brightness behavior: A 25% duty cycle does not always appear exactly one-quarter as bright because human vision responds nonlinearly. A perceptual brightness scale may therefore use a lookup table or gamma correction.
-
Inverted wiring: If an LED is connected from 3.3 V to a GPIO and the GPIO sinks current, the logic is inverted: a low PWM value can produce greater brightness. In that case, the effective command can be calculated approximately as:
[
x_{\text{effective}}=1023-x
]
C. Applications and Limitations
LED PWM is suitable for indicators, night lights, status displays, and dimmable lighting, but the GPIO must remain within its electrical limits.
-
Applications: PWM can create a breathing indicator, provide adjustable illumination, or represent a sensor value. For example, a temperature value can be mapped from 0–100 °C to a PWM range of 0–1023.
-
Resolution: The default 10-bit range provides 1024 possible duty-cycle commands. The visual difference between adjacent values may be unnoticeable at low brightness.
-
Frequency selection: The ESP8266 Arduino core commonly uses approximately 1 kHz by default.
analogWriteFreq(frequency)can change the frequency when flicker or audible effects matter. -
Protection: Never connect an LED directly to a GPIO without a resistor. Excessive current can damage both the LED and the ESP8266 output driver.
III. Servo Motor Control Using PWM
A. Purpose and Principle
A hobby servo uses repeated control pulses, usually at about 50 Hz, to determine shaft position. Unlike LED brightness control, servo position depends mainly on pulse width rather than the average voltage or duty cycle.
B. Servo motor control using pwm
A typical servo receives a 20 ms period and interprets a pulse of approximately 1 ms as one end position, 1.5 ms as the center, and 2 ms as the other end. Actual limits vary by servo model.
-
Control signal: The standard period is approximately:
[
T=20\text{ ms},\qquad f=\frac{1}{0.020}=50\text{ Hz}
]The pulse width (t_p), rather than ordinary LED-style duty percentage, carries the position command.
-
Position relationship: For a servo configured between 0° and 180°, a simplified mapping is:
[
t_p\approx1\text{ ms}+\frac{\theta}{180}(1\text{ ms})
]Here, (\theta) is the requested angle in degrees. Thus, 90° corresponds approximately to a 1.5 ms pulse.
-
Power connection: Connect the servo signal wire to a NodeMCU GPIO, connect the servo ground to NodeMCU ground, and power the servo from a suitable 5 V supply when required.
- External supply: A servo can draw high startup or stall current, so powering it directly from the NodeMCU 3.3 V pin is inappropriate.
- Common ground: The external servo supply ground and NodeMCU ground must be connected so the signal has a shared reference.
- Voltage compatibility: Confirm that the servo recognizes a 3.3 V control signal. Many hobby servos do, but this is not universal.
-
Program using a servo library: The library generates the repeated timing waveform.
#include <Servo.h>
Servo positionServo;
const int servoPin = D5; // servoPin identifies the signal connection
void setup() {
positionServo.attach(servoPin);
}
void loop() {
positionServo.write(0);
delay(1000);
positionServo.write(90);
delay(1000);
positionServo.write(180);
delay(1000);
}-
Symbol definitions:
positionServois the servo object,servoPinis the NodeMCU control pin, andwrite(angle)requests an angle in degrees. -
Pulse-width control: For finer calibration,
writeMicroseconds()can specify a pulse directly.
positionServo.writeMicroseconds(1500);The value 1500 represents a 1.5 ms pulse and commonly commands the center position.
-
Worked example: If a servo is specified for 0° at 1000 µs and 180° at 2000 µs, the approximate 120° pulse is:
[
t_p=1000+\frac{120}{180}(1000)=1667\ \mu s
]
C. Applications and Limitations
Servo PWM is useful when an angular position must be selected and maintained, but it is not intended to control continuous motor speed in the same way as a DC motor.
-
Applications: Servos operate pan-and-tilt mechanisms, robotic joints, valve controls, pointer instruments, and model steering systems.
-
Mechanical limits: Commanding exactly 0° or 180° may force some servos against their physical stops. A safer tested range might be 10° to 170°.
-
Jitter: Unstable power, electrical noise, or timing interference can cause small position changes. A separate regulated supply and short signal wiring can reduce this effect.
-
Load limitation: The servo must provide enough torque for the mechanism. PWM selects the target position, but it cannot compensate for an overloaded gearbox or insufficient supply current.
-
ESP8266 resources: Servo libraries use timing resources and may interact with other software PWM outputs. Timing-sensitive applications should avoid creating unnecessary blocking delays.
IV. DC Motor Control Using PWM
A. Purpose and Principle
A DC motor’s speed can be adjusted by applying PWM through a transistor or motor-driver module. The driver rapidly switches motor current, while the motor’s inductance and mechanical inertia smooth the pulses into an average torque and speed.
B. DC motor control using pwm
NodeMCU should provide only the low-current control signal; the motor current must flow through a suitable driver such as an L298N, TB6612FNG, or a logic-level MOSFET circuit.
-
Driver arrangement: A basic single-direction circuit uses a PWM input on the driver’s enable pin. A bidirectional H-bridge uses direction inputs plus a PWM enable input.
- Power path: The motor receives current from an external motor supply.
- Control path: NodeMCU GPIO signals select enable, direction, or speed.
- Protection path: A driver normally includes flyback diodes or other switching protection. A discrete transistor circuit requires a flyback diode across the motor.
-
Speed relationship: For a motor supply (V_s), the approximate average applied voltage is:
[
V_{\text{AVG}}\approx D V_s
]A 60% duty cycle on a 9 V motor supply gives an ideal average of approximately 5.4 V. Actual speed also depends on load, friction, motor resistance, and driver voltage drop.
-
Simple one-direction program: This example controls the enable input of a motor driver.
const int motorEnable = D2; // PWM input of the motor driver
void setup() {
pinMode(motorEnable, OUTPUT);
analogWrite(motorEnable, 0);
}
void loop() {
analogWrite(motorEnable, 300);
delay(2000);
analogWrite(motorEnable, 700);
delay(2000);
analogWrite(motorEnable, 0);
delay(1000);
}300 corresponds to approximately 29% duty cycle, and 700 corresponds to approximately 68%. motorEnable is the GPIO connected to the driver’s enable or speed-control input.
- Direction control: With an H-bridge, two digital outputs can select direction while a PWM output controls speed.
const int directionA = D6;
const int directionB = D7;
const int motorEnable = D2;
void setup() {
pinMode(directionA, OUTPUT);
pinMode(directionB, OUTPUT);
pinMode(motorEnable, OUTPUT);
digitalWrite(directionA, HIGH);
digitalWrite(directionB, LOW);
analogWrite(motorEnable, 600);
}HIGH/LOW on the direction pins selects one rotation direction; reversing both direction signals reverses the motor.
- Starting behavior: Motors may not rotate at very low duty cycles because static friction and load torque exceed the available starting torque. A brief higher-duty startup pulse can be used before reducing speed.
C. Applications and Limitations
Motor PWM supports variable-speed actuators, fans, pumps, wheels, and small robotic platforms, but safe operation depends on driver selection and electrical design.
-
Applications: A robot can use separate PWM channels for left and right motors, allowing speed adjustment and turning. A fan controller can vary airflow without continuously wasting power in a series resistor.
-
Driver current rating: Select a driver for the motor’s stall current, not only its no-load running current. A motor marked 500 mA during normal operation may draw several amperes when stalled.
-
Voltage drop: Bipolar drivers such as some L298N modules can lose significant voltage internally. A motor supplied with 9 V may receive substantially less under load.
-
Noise and resets: Motor commutation creates electrical interference and supply dips. Use short power wiring, suitable decoupling capacitors, separate motor and logic supply paths where practical, and a common ground at an appropriate point.
-
Safety: Never connect a motor directly between a NodeMCU GPIO and ground. The inductive load can generate a voltage spike when switched off, permanently damaging the GPIO or resetting the controller.
-
Control precision: Open-loop PWM sets a command, not an exact speed. Maintaining constant RPM requires feedback, such as an encoder, and a control algorithm that adjusts the duty cycle according to measured speed.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →