PWM LED control with ESP32 and IoT Platform over MQTT

From anywhere in the world, you can control your PWM actuators with AskSensors IoT platform; The ESP32 board integrates PWM ( Pulse Width Modulation) controller that supports up to sixteen channels. We can get the PWM signal from GPIO pins to fade LED brightness, servomotors speed or any actuator that supports PWM control.

In this tutorial, you will learn how to control the LED brightness remotely using the ESP32 PWM and the AskSensors IoT platform over MQTT.

1) Prerequisites :

Followings are the prerequisites and backgrounds concepts you need to completely understand this tutorial and control your own PWM systems with ESP32 and AskSensors.

  • Subscribe to AskSensors account.
  • Create a new actuator device with at least one module to control your LED.
  • Now after this click on ‘Add command’ and select a Slider command type.
  • Copy down your actuator API KEY OUT, we will use it later.

2) Parts required

  • ESP32 development board.
  • Breadboard
  • 5mm LED
  • 330Ω Resistor
  • Jumper wires
  • Computer running Arduino IDE software.
  • USB micro cable to connect ESP32 development board to the computer.

3) Circuit schematic

The following image shows the schematic diagram of the circuit used in this tutorial.

  • Connect the negative pin (cathode) of the LED, indicated as the flat edge of the LED to ground.
  • Similarly, connect the positive pin (anode) of the LED, indicated as the rounded edge of the LED to a 100Ω resistor.
  • Now, connect the free end of the resistor to pin GPIO5 on the ESP32.
  • Last, connect your ESP32 to the computer through a USB cable. The ESP32 will be powered from the USB 5V.

4) Install the ESP32 in Arduino IDE

The ESP32 will be programmed using Arduino IDE. There’s an add-on for the Arduino IDE (1.8.7 or higher) that allows you to program the ESP32 using the Arduino IDE and its programming language. Follow the instructions below:

  • Open the preferences window from the Arduino IDE : File> Preferences.
  • Go to the “Additional Board Manager URLs” field, Enter the following URL:
https://dl.espressif.com/dl/package_esp32_index.json
  • If you already have the ESP8266 boards URL, separate the URLs with a comma as shown below:
https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.jso
  • Open boards manager (Tools > Board > Boards Manager), search for ESP32 and click the install button for the “ESP32 by Espressif Systems”.

5) Download the libraries

  • The PubSubClient library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT.

o Download the PubSubClient library from github.

o Unzip the .zip folder and you should get pubsubclient-master folder

o Rename your folder from pubsubclient-master to pubsubclient

o Move the pubsubclient folder to your Arduino IDE installation libraries folder

o Then, re-open your Arduino IDE

o The library comes with a number of example sketches that are not fully compatible with the ESP32. However, the example provided in this tutorial is working very reliably in the Arduino IDE software.

6) Configure the ESP32 PWM channel

Three functions are used to set the PWM parameters:

  • ledcSetup(PWM_channel, PWM_freq, PWM_resolution): To set the channel, frequency and resolution of the PWM controller
  • ledcAttachPin(PWM_pin , PWM_channel) : To set the One is used to set the PIN with the channel.
  • ledcWrite(PWM_channel, PWM_cmd): To generate the signal with the duty cycle that corresponds to the command received from the AskSensors user.

Below are the PWM parameters that we selected for this tutorial.

  • PWM_channel = 0: There are 16 PWM channels available. You need to choose any channel between 0 and 15.
  • PWM_freq = 5000: The second step is to choose the frequency of the digital signal.  You can set the frequency at 5000 hertz or any other value you want.
  • PWM_resolution= 8: ESP32 boards support PWM resolution between 1 bit to 16 bits. We will be using 8-bit resolution, and duty cycle value will vary between 0-255. Duty cycle defines the ON time of the signal.
  • PWM_pin = 5: The last step is to attach the GPIO PIN with a PWM channel of your own choice.

7) Upload the code

Now, we can upload the following code to your ESP32 following the steps below:

  • Download this complete demo from the AskSensors github page. You need to edit the code with your own SSID, password and MQTT topic (username/apiKeyOut)
//TODO: ESP32 MQTT user config

const char* ssid = ".............."; // Wifi SSID

const char* password = ".............."; // Wifi Password

const char* username = ".............."; // my AskSensors username

const char* subTopic = "actuator/............../.............."; // actuator/username/apiKeyOut

const int PWM_pin = 5; // LED pin

  • Connect your ESP32 board to your computer through the micro-USB cable. Make sure the red LED goes high on the module to ensure power supply.
  • Open your arduino IDE and select Tools options for your ESP32 Dev. board type and serial port where it’s connected then click upload. The code will be running automatically after Reset.
  • Now, we will send command from the AskSensors web application to control the LED brightness level.
    • Sending 0 will turn off the LED
    • Sending 50 in the command will turn ON the LED at 50% of its maximum brightness level.
    • Sending 100% will fade the LED with the maximum brightness level.

7) Source code

The source code is below. Refer to the AskSensors Github page to get the latest version and updates.

/*

* Description:  Control LED with AskSensors and ESP32 dev board over MQTT

*  Author: https://asksensors.com, 2020

*  github: https://github.com/asksensors

*/

#include <WiFi.h>

#include <PubSubClient.h>

#include <Wire.h>

//TODO: ESP32 MQTT user config

const char* ssid = ".............."; // Wifi SSID

const char* password = ".............."; // Wifi Password

const char* username = ".............."; // my AskSensors username

const char* subTopic = "actuator/............../.............."; // actuator/username/apiKeyOut

// PWM config

const int PWM_pin = 5;

const int PWM_freq = 5000;

const int PWM_channel = 0;

const int PWM_resolution = 8;

float pwm_cmd = 0;

//AskSensors MQTT config

const char* mqtt_server = "mqtt.asksensors.com";

unsigned int mqtt_port = 1883;

// MQTT client

WiFiClient askClient;

PubSubClient client(askClient);

void setup() {

Serial.begin(115200);

Serial.println("*****************************************************");

Serial.println("********** Program Start : Controling ESP32 PWM with AskSensors over MQTT");

Serial.println("PWM setup");

ledcSetup(PWM_channel, PWM_freq, PWM_resolution); // PWM setup

ledcAttachPin(PWM_pin, PWM_channel);

Serial.print("********** connecting to WIFI : ");

Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

Serial.println("");

Serial.println("->WiFi connected");

Serial.println("->IP address: ");

Serial.println(WiFi.localIP());

client.setServer(mqtt_server, mqtt_port);

client.setCallback(callback);

if (!client.connected())

reconnect();

Serial.print("********** Subscribing to AskSensors actuator topic:");

Serial.print(subTopic);

// susbscribe

client.subscribe(subTopic);

}

void loop() {

client.loop();

ledcWrite(PWM_channel, pwm_cmd);

}

void callback(char* topic, byte* payload, unsigned int length) {

Serial.print("\nCommand received from AskSensors[");

Serial.print(topic);

Serial.print("] ");

char command_str[8];

char module_str[length-8];

Serial.print("\nModule: ");

for (int i = 0; i < 8; i++) {

module_str[i] = (char)payload[i];

Serial.print((char)module_str[i]);

}

Serial.print("\ncommand: ");

for (int i = 0; i < length-8; i++) {

command_str[i] = (char)payload[i+8];

Serial.print((char)command_str[i]);

}

Serial.println("\n********** Parsing Actuator command");

if(strncmp((char *)module_str, (char*) "module1=",8)== 0){

pwm_cmd = (float)atoi((char*)command_str);

// conversion from max=100% PWM to 8-bits output

pwm_cmd *= 255.0/100;

Serial.print("PWM Ratio:");

Serial.print(pwm_cmd);

Serial.println("%");

}

}

void reconnect() {

// Loop until we're reconnected

while (!client.connected()) {

Serial.print("********** Attempting MQTT connection...");

// Attempt to connect

if (client.connect("ESP32Client", username, "")) {

Serial.println("-> MQTT client connected");

} else {

Serial.print("failed, rc=");

Serial.print(client.state());

Serial.println("-> try again in 5 seconds");

// Wait 5 seconds before retrying

delay(5000);

}

}

}

What’s next?

Now that you have got the basics , you can try controlling other PWM actuators with AskSensors.

The more you learn the more you grow, so don’t stop here.

Feel free to comment if you have any questions about this tutorial.

5 Comments
  1. My esp is subscribing. But no response when command sent. I doubt about user name

  2. worked with user name without space 🙂

    Leave a Reply to himrawnn Cancel reply