ESP8266 PWM Example with Javascript and AJAX

Here we demonstrate how ESP8266 WiFi module can be used to generate PWM signal to control the brightness of a LED wirelessly. The ESP8266 is configured as a web server and clients/users can change the PWM duty cycle with a slider on a web page hosted in the asynchronous ESP8266 web server. When the ESP8266 server receives the PWM request via web browser from PC or mobile phones, it sends the PWM value to the LED connected to it. For server client interaction we use Javascript and AJAX. So all interaction is asynchronous which allows more efficient client connection with relatively lower server load. This simple LED brightness control can be extended to control other external devices such as DC motor. So many IoT application can be build based on this simple LED example where wireless PWM signal control of devices is required. Here we will be using internal WiFi connection which can be useful for Home IoT application. But this can be publicly made available using cloud IoT platform.

ESP8266 Wifi module as web server
 Here we have used ESP12E WiFi module which is a version of ESP8266. But any other ESP8266 based board such as ESP32 or NodeMCU can be used. Also we have used asynchronous Web server using the ESPAsyncWebServer and ESPAsyncTCP libraries. For ESP32 you will need to use AsyncTCP library instead of ESPAsyncTCP. This aynchronous libraries was explained in the tutorial Simple ESP8266 Asynchronous Web Server Example with Code.

Recommended Prerequisites

- PWM example using ESP8266 ESP12E

Interfacing and Schematic Diagram

The following picture shows the interfacing of ESP12E (version of ESP8266) connected with LED at GPIO pin 13 on a breadboard.

ESP12E (ESP8266) and LED on breadboard

The following picture shows the schematic diagram used in this tutorial.schematic wiring ESP12E (ESP8266) and LED

Video Demonstration

The following video demonstrates how users can control the LED brightness via website with ESP12E as a asynchronous web server. In the video, you will see how to use the ESP8266 to create a simple wireless LED dimmer. The video starts by showing the components required for the project, including the ESP8266 module, a LED, and a few other basic components. Then, it goes on to explain the programming and wiring required to set up the ESP8266 and connect it to the LED. The video also covers the different aspects of the code, such as the PWM signal generation, and how to control the brightness of the LED wirelessly using a mobile app or web interface. This video is a great resource for anyone looking to learn more about using the ESP8266 to generate PWM signals and control the brightness of a LED wirelessly. It is well-explained, easy to follow, and provides a step-by-step guide to help you build your own wireless LED dimmer with ESP8266.

 

Program Code

The following are two source code files to program ESP8266 as a asynchronous web server with a web page that allows clients to change the PWM signal duty cycle and send PWM signal to the LED for brightness control.

The first is the PWMasyncwebserverJs.ino which contains the program code to set up wifi connection, client and server interaction logic. The second file is indexHtml.h file which contains the HMTL code along with CSS and Javascript codes to render the web page look and client side application logic.

PWMasyncwebserverJs.ino

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "indexHtml.h"


const int LEDpwm = 13;

const char ssid[]="yourSSID";
const char password[]="yourPASSWORD";


AsyncWebServer server(80);

void setup() {
  pinMode(LEDpwm, OUTPUT);
  Serial.begin(115200);

  Serial.printf("Connecting to %s....\n", ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if(WiFi.waitForConnectResult() != WL_CONNECTED){
    Serial.printf("WiFi connection failed!\n");
    delay(1000);
    ESP.restart();
    }
  Serial.printf("Connected to %s\n", ssid);
  Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
    }
    );

  server.on("/ajaxPage", HTTP_POST, [](AsyncWebServerRequest *request){
    AsyncWebParameter *p = request->getParam(0);
      if(p->isPost()){
        Serial.printf("PWM Value:%s\n",p->value().c_str()); 
        }
      analogWrite(LEDpwm, p->value().toInt()); 
      
      request->send(303);
      }
    );

  server.begin();
}

void loop() {

}

 In the above program code, we have done the followings:

* We have included the ESP8266WiFi.h, ESPAsyncWebServer and ESPAsynchTCP libraries to build the asynchronous web server and for WiFi connection.

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

* We have included the indexHTML.h header file which contains the HTML, CSS and Javascript code stored in the PROGMEM of the flash memory.

#include "indexHtml.h"

* We have created an alias LEDpwm for the GPIO pin 13

const int LEDpwm = 13;

* Then we have setup the WiFi network credentials

Note that this must be replaced with your own WiFi SSID and PASSWORD credentials. You must replace these with your WiFi access point credentials.

const char ssid[]="yourSSID";
const char password[]="yourPASSWORD";

* Using AsyncWebServer server(80) we have create server object with port number 80.

* In the setup() function, we have first set up the LED pin as output up and set the baud rate of 115200 for serial communication with the ESP12E wifi module.

pinMode(LEDpwm, OUTPUT);
  Serial.begin(115200);

We then print message to the user "connecting to... " ssid provided to inform progress of connection behind the scene which users can see on the Arduino IDE serial monitor. Using WiFi.mode() we have setup the ESP8266mod into Station mode.  Using if(WiFi.waitForConnectResult() ) statement we check for wifi connection to Access Point(AP). If the connection fails then we print message "WiFi connection failed!\n" to inform users that connection has failed. If the connection is successful, we print out message "Connected to " ssid and also print out the IP address to inform the user at which IP address it is connected to.

Serial.printf("Connecting to %s....\n", ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if(WiFi.waitForConnectResult() != WL_CONNECTED){
    Serial.printf("WiFi connection failed!\n");
    delay(1000);
    ESP.restart();
    }
  Serial.printf("Connected to %s\n", ssid);
  Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str());

Using the on method of server object created earlier, server.on(), we create a handler that handles the HTTP request from incoming clients. Whenever there is request, we send the content of the index_html loaced in the indexHtml.h file and stored in the program space.

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
    }
    );

We create another handler that gets the PWM value from the slider input whenever there is slider position changes back to the server. We print out to the Arduino serial monitor the value read. Then PWM signal is generated on GPIO pin 13 or the LED pin with the analogWrite() function where the PWM value received from the slider input is passed into.

 server.on("/ajaxPage", HTTP_POST, [](AsyncWebServerRequest *request){
    AsyncWebParameter *p = request->getParam(0);
      if(p->isPost()){
        Serial.printf("PWM Value:%s\n",p->value().c_str());
        }
      analogWrite(LEDpwm, p->value().toInt());
      
      request->send(303);
      }
    );

* Finally the server.begin() is used to start the asynchronous web server.

 server.begin();

#Nothing is required in the loop() function since we are using asynchronous web server that uses handlers automatically to interact with the clients requests.

indexHtml.h

const char index_html[] PROGMEM = R"=====(
<html>
  <head>
    <title>ESP12E PWM LED Control with AJs</title>
    <style>
      body {
      padding: 40px;
      text-align: center;
      }  
    </style>

  </head>
  <body>
    <p>PWM Slider</p>
      <input type="range" name="pwmSliderName" min="0" max="1023" value="0" id="pwmSliderID">
    <script>
      document.getElementById("pwmSliderID").oninput = function(){
      var postReq = "pmw_value=" + document.getElementById("pwmSliderID").value;
      var xhttp = new XMLHttpRequest();
      xhttp.open("POST", "ajaxPage", true);
      xhttp.send(postReq);
    };
    </script>

  </body>
</html>

)=====";


* We have placed our HTML, CSS, Javascript, AJAX code inside the character array called index_html in the program memory space as string literal. In the HTML code we have used title tag to give the web page a title. We have used some CSS code using <style> to center the displayed text on the center and below the top of 40px. In the body section we have used the slider input to read PWM value from clients. After this javascript and AJAX codes have been used to read in the value from the slider input and feedback this information to the web server using AJAX.

const char index_html[] PROGMEM = R"=====(
<html>
  <head>
    <title>ESP12E PWM LED Control with AJs</title>
    <style>
      body {
      padding: 40px;
      text-align: center;
      }  
    </style>

  </head>
  <body>
    <p>PWM Slider</p>
      <input type="range" name="pwmSliderName" min="0" max="1023" value="0" id="pwmSliderID">
    <script>
      document.getElementById("pwmSliderID").oninput = function(){
      var postReq = "pmw_value=" + document.getElementById("pwmSliderID").value;
      var xhttp = new XMLHttpRequest();
      xhttp.open("POST", "ajaxPage", true);
      xhttp.send(postReq);
    };
    </script>

  </body>
</html>

)=====";

Thus in this ESP8266 Web Server tutorial we have show how we can control the LED brightness with ESP8266 WiFi module as a web server with client slider input to generate PWM signal wirelessly. This simple web server client interaction with LED can be applied in making all kinds of IoT application. For example we can use this ESP8266 web server for DC motor control using L293D Motor Shield.

Post a Comment

Previous Post Next Post