The objective of this post is to explain how to use the Pulse Width Modulation (PWM) technique with the ESP8266 and the main differences of the implementation comparing with the Arduino.
Pulse Width Modulation
In the PWM technique, we produce a square wave with a controllable duty cycle. This means that we can control, for each period of the wave, how much time it is at VCC (HIGH) or GND (LOW). So, it’s typical for the duty cycle to be specified as the percentage of time in which the WAVE is on an HIGH state, in a period, in respect to the period.
This way, PWM allows us to encode an analog value digitally and control an analog circuit . In other words, we can simulate analog voltages between GND and VCC.
Some example applications are controlling the intensity of a LED or the speed of a motor using a signal produced by a microcontroller (naturally, for the motor, by using a transistor or other device to supply the current needed to move it).
The ESP8266 analogWrite
We assume the use of the ESP8266 libraries for the Arduino IDE. You can check here how to configure the Arduino IDE to support the ESP8266.
So, in order to use PWM, we can call the analogWrite function, which is a function also available (and commonly used) when programming Arduino boards. Nevertheless, there are some differences between the implementation for Arduinos and for the ESP8266.
In both cases, this function receives as arguments the pin where to produce the PWM signal and a parameter to specify the duty cycle. Although, as mentioned in the previous section, the duty cycle is typical specified as a percentage, this function receives a value between 0 and another value different from 100.
In the case of the ESP8266 implementation, we can pass a value between 0 (wave always with a value of GND) and 1023 (wave always with a value of VCC) for the duty cycle. Nevertheless, this range can be changed with a call to the analogWriteRange function .
For the Arduino implementation of most boards, we can only define a value between 0 and 255 for the duty cycle , which is a lower resolution than for the ESP8266. Nevertheless, for some boards such as the Arduino Due, we can call the AnalogWriteResolution function to increase this resolution.
Other difference is that we need to call the AnalogWrite function with a value of 0 for the duty cycle in order to disable the PWM on that pin, in the case of the ESP8266.
If we don’t do it, the next calls to the digitalWrite function on that pin will not work. On the contrary, for Arduino boards implementation, a call to digitalWrite will disable PWM on that pin .
As for the frequency of the square wave produced on the ESP8266, the default value is 1KHz. Nevertheless, we can change it with a call to the analogWriteFreq function.
For the Arduino implementation, the frequency depends on the board used .
- Implementation of PWM for the ESP8266
- ESP8266 analog output reference
- AnalogWrite function for arduino boards
- Different implementations of PWM
- ESP8266 libraries: v2.3.0.