ESP32, PWM and Blynk

Hi Blynkers,
I wanted to share a small set-up using a simple RGB led with the ESP32 (Lolin32) doing PWM. This is not a “project” by itself but I guess, it could be useful to other Blynkers cause at the moment, the analogWrite() function is not implemented. It should be useful for DC motors, Robots…

The set-up couldn’t be more simple:

The code (Remember I’m a Local Server guy, change it accordingly…):

#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
BlynkTimer timer;

//********************* SECTION FOR YOU TO COMPLETE WITH YOUR DETAILS *************
// Get Auth Token in the Blynk App.

char auth[] = "xxxxxxxx"; // Token
char cloudserver[16] = "";
char localserver[16] = "";          // Enter your IP details for the local server
char ssid[] = "xxxxxxxxxx";                   // Your WiFi credentials.
char pass[] = "xxxxxxxxxxxx";                     // Set password to "" for open networks.

//********************* CLOCK DETAILS *********************************************
#include <WidgetRTC.h>//Blynk
WidgetRTC rtc;

//********************* LED DETAILS *********************************************
uint8_t led1 = 12;
uint8_t led2 = 13;
uint8_t led3 = 14;
int PWM_LED1;
int PWM_LED2;
int PWM_LED3;

bool isFirstConnect = true;

if (isFirstConnect) {
Blynk.notify("ESP32 Starting!!");
isFirstConnect = false;

void setup()
ledcAttachPin(led1, 1); // assign RGB led pins to channels
ledcAttachPin(led2, 2); // assign RGB led pins to channels
ledcAttachPin(led3, 3); // assign RGB led pins to channels
  // Initialize channels 
  // channels 0-15, resolution 1-16 bits, freq limits depend on resolution
  // ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
ledcSetup(1, 12000, 12); // 12 kHz PWM, 12-bit resolution
ledcSetup(2, 12000, 12); // 12 kHz PWM, 12-bit resolution
ledcSetup(3, 12000, 12); // 12 kHz PWM, 12-bit resolution

  // Debug console
  Serial.println("\n Starting");
  //Blynk.begin(auth, ssid, pass);              // normal Blynk Cloud server connection     
 // Blynk.config(auth, cloudserver);            // for Blynk's cloud server if WiFi already connected
  Blynk.begin(auth, ssid, pass, localserver);   // for a local server requiring WiFi connection
  int mytimeout = millis() / 1000;
  while (Blynk.connect() == false) {        // wait here until connected to the server
    if((millis() / 1000) > mytimeout + 8){      // try to connect to the server for less than 9 seconds
      break;                                    // continue with the sketch regardless of connection to the server
  rtc.begin(); //RTC clock begin
  timer.setInterval(15000, reconnectBlynk); // check every 15 seconds if we are connected to the server
  timer.setInterval(5000L, clockvalue);  // check value for time
  timer.setInterval(5000L, sendWifi);    // Wi-Fi singal


void reconnectBlynk() // reconnect to server if disconnected, timer checks every 15 seconds
  if (!Blynk.connected()) {
    if(Blynk.connect()) {
    } else {
      BLYNK_LOG("Not reconnected");

void sendWifi() {
 int wifisignal = map(WiFi.RSSI(), -105, -40, 0, 100);
  Blynk.virtualWrite(V10, wifisignal);  

void clockvalue() // Digital clock display of the time
 int gmthour = hour();
  if (gmthour == 24){
     gmthour = 0;
  String displayhour =   String(gmthour, DEC);
  int hourdigits = displayhour.length();
  if(hourdigits == 1){
    displayhour = "0" + displayhour;
  String displayminute = String(minute(), DEC);
  int minutedigits = displayminute.length();  
  if(minutedigits == 1){
    displayminute = "0" + displayminute;

  String displaycurrenttime = displayhour + ":" + displayminute;
  Blynk.virtualWrite(V11, displaycurrenttime);

BLYNK_WRITE(V0) //slider in Virtual Pin 0 (0...4095)
 PWM_LED1 = param.asInt();
 ledcWrite(1, PWM_LED1); // write red component to channel 1, etc. 0-4095
 float voltage1 = map(PWM_LED1, 0, 4095, 0, 330);
 Blynk.virtualWrite(V3, voltage1/100);  

BLYNK_WRITE(V1) //slider in Virtual Pin 1 (0...4095)
 PWM_LED2 = param.asInt();
 ledcWrite(2, PWM_LED2); // write red component to channel 1, etc. 0-4095
 float voltage2 = map(PWM_LED2, 0, 4095, 0, 330);
 Blynk.virtualWrite(V4, voltage2/100); 

BLYNK_WRITE(V2) //slider in Virtual Pin 2 (0...4095)
 PWM_LED3 = param.asInt();
 ledcWrite(3, PWM_LED3); // write red component to channel 1, etc. 0-4095
 float voltage3 = map(PWM_LED3, 0, 4095, 0, 330);
 Blynk.virtualWrite(V5, voltage3/100); 

void loop()
if (Blynk.connected()) {   // to ensure that function is only called if we are still connected to the server;

The dashboard:
(I’m sorry but at the moment there’s no way to Clone the Project properly)

Other picture showing the result of the tester VS the V.out calculated in the code (2.05V vs 2.09V, quite good!)

The video:

I hope you like it!!


@psoro have the “ESP” suppliers finally seen the light and used GPIO numbers on their boards? Looks like it from what I can see. Well maybe half way there, just digital pins numbered correctly.

Yep, at least in this board, BUT, the way they added the labels in one of the sides is not really friendly, the number is located between two pins and could be misleading . The other side is better, see both below:

Especially for the directionally challenged :wink: I keep having to look at the top or bottom pins to reorient myself as to whether the number refers to the upper or lower pin.

I have managed to use this simple code to move a servo on the same type board… And nope, I don’t understand how it works, but it works :stuck_out_tongue:

Is it using a similar method as yours?

#include "esp32-hal-ledc.h" // For Servo option - this seems to be the secret sauce library

// In setup
ledcSetup(1, 50, 16); // For Servo option - channel 1, 50 Hz, 16-bit width
ledcAttachPin(2, 1);   // For Servo option - GPIO 2 assigned to channel 1

// Slider function - For my servo the best range was 1900-8200
  ledcWrite(1, param.asInt() );  // write position to channel 1

It seems really similar to “my” method… I’m in the same step as you are, the code woks but I don’t understand the way it works…:sweat_smile:

That’s exactly what I do every time! :blush:

Many thanks for this piece of code, it could be really useful! what I don’t understand is the range 1900-8200… Can you please be so kind to explain it a little bit?

Did you obtain your piece of code from here?:

That is the range I set on the Slider Widget to go from stop to stop without buzzing from overshoot… it was extrapolated from the original example and some trial and error.

No… I was Googling “Control Servo on ESP32” and one site had this example…

mmm… good! I think I’m going to play a little bit with several servos before going to sleep… :wink:
Thanks @Gunner!

I think you can control up to 8 serves with that method based on the channel numbers?

I’ve got 4 to play with, two of them hacked to run 360º
Let’s see what happens!


The 2 Servos are working fine using your range and 3.3V
The RGB is working also

I’m afraid it’s time to go to sleep…:sleeping:

1 Like

This is what it looks like in Blynk’s dark theme on an ESP32

And QR code for Blynk’s cloud server (url might be )


Hello. I am Japanese. I have a question. Where can I get the library of <WiFi.h> <WiFiClient.h> <BlynkSimpleEsp32.h> <WidgetRTC.h> with this program? Also, if there is anything else you need, please help.

out of all the examples yours has been the most helpful
thanks very much!!!

1 Like

Thanks for this- got me going with RGB Led, couldnt find a simple answer anywhere for ESP32!

1 Like