top of page
Writer's pictureRamesh G

NodeMCU Web Server Controlled Relay with OLED


In this tutorial, I 'll Publish how to controlling Relay channel board using web server over WiFi using NodeMCU and OLED display. In this project, web page without refresh application uses javascript ajax and On/Off Flip Switch (CSS3 ) is used with animated transitions.



Circuit Diagram



Components Required

0.96 OLED 4wire Module - 1no

Node MCU ESP8266 12E Dev Module- 1 no


4 Channel Relay Module


The four-channel relay module contains four 5V relays and the associated switching and isolating components, which makes interfacing with a microcontroller or sensor easy with minimum components and connections. The contacts on each relay are specified for 250VAC and 30VDC and 10A in each case, as marked on the body of the relays.

The driver circuit for this relay module is slightly different compared to traditional relay driving circuits since there is an optional additional layer of isolation. When the jumper is shorted, the relay and the input share the same VCC, and when it is open, a separate power supply must be provided to the JD-VCC jumper to power the relay coil and optocoupler output.


The inputs for this module are active low, meaning that the relay is activated when the signal on the input header is low. This is because the indicator LED and the input of the optocoupler are connected in series to the VCC pin on one end, so the other end must be connected to the ground to enable the current flow. The optocouplers used here are the PCF817, which is a common optocoupler and can also be found in through-hole packaging.


Download DATASHEET


Installing Library

To install the library navigate to the Sketch > Include Library > Manage Libraries… Wait for Library Manager to download libraries index and update list of installed libraries.

Installing SSD1306 OLED Library – ESP8266

There are several libraries available to control the OLED display with the ESP8266. In this tutorial we’ll use two Adafruit libraries:

Adafruit_SSD1306 library Download

Adafruit_GFX library. Download


After installing the required libraries, copy the following code to your Arduino IDE.



arduino code

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>


#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


/********** PLEASE CHANGE THIS *************************/

const char* ssid = "TP-Link_3200"; // your wifi name

const char* password = "95001121379884265554"; // your wifi password


ESP8266WebServer server(80);


uint8_t RELAY1Pin = D7;

uint8_t RELAY2Pin = D6;

uint8_t RELAY3Pin = D5;

uint8_t RELAY4Pin = D4;


bool RELAY1Status = LOW;

bool RELAY2Status = LOW;

bool RELAY3Status = LOW;

bool RELAY4Status = LOW;


/***********************************/

#define bitmap_height 61

#define bitmap_width 22

static const unsigned char PROGMEM bitmap1F[] =

{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8,

0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xe7, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78,

0xce, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0x90, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x30, 0x00, 0x78, 0x3c, 0xfc, 0x18, 0x61, 0xc8,

0x20, 0x00, 0x3b, 0x98, 0xf9, 0xc9, 0xef, 0xe0, 0x20, 0x00, 0x3b, 0x90, 0xf9, 0xe9, 0xef, 0xe0,

0x20, 0x00, 0x38, 0x3c, 0xfb, 0xe8, 0x63, 0xe0, 0x20, 0x00, 0x39, 0x7c, 0xfb, 0xe9, 0xef, 0xe0,

0x20, 0x00, 0x3b, 0x3c, 0xf9, 0xe9, 0xef, 0xe0, 0x20, 0x00, 0x7b, 0x9c, 0xfd, 0xc9, 0xef, 0xe8,

0x30, 0x00, 0x7b, 0x9c, 0xfe, 0x39, 0xef, 0xc8, 0x30, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8,

0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xcc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0xe7, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x78,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8

};

static const unsigned char PROGMEM bitmap1N[] =

{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,

0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x98, 0x81, 0xf0, 0x40, 0x78, 0xc8, 0x0f, 0xff, 0x88,

0x01, 0x98, 0xc0, 0xcc, 0xcc, 0x1f, 0xff, 0xc8, 0x01, 0x89, 0xc0, 0x84, 0xec, 0x1f, 0xff, 0xc0,

0x01, 0x98, 0xc1, 0x86, 0xec, 0x1f, 0xff, 0xc0, 0x01, 0xf0, 0xc1, 0x86, 0xfc, 0x1f, 0xff, 0xc0,

0x01, 0xb0, 0xc1, 0x84, 0x9c, 0x1f, 0xff, 0xc0, 0x01, 0x98, 0xc0, 0x8c, 0x9c, 0x1f, 0xff, 0xc8,

0x01, 0x98, 0xc0, 0xf8, 0x9c, 0x0f, 0xff, 0xc8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x88,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x38,

0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,

0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8

};

static const unsigned char PROGMEM bitmap2F[] =

{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8,

0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xe7, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78,

0xce, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0x90, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x30, 0x00, 0x70, 0x78, 0xfe, 0x1e, 0x18, 0x48,

0x20, 0x00, 0x37, 0x33, 0x7c, 0xe6, 0xfb, 0xe0, 0x20, 0x00, 0x37, 0xbf, 0x7d, 0xf6, 0xfb, 0xe0,

0x20, 0x00, 0x37, 0x3e, 0x7d, 0xf6, 0xfb, 0xe0, 0x20, 0x00, 0x30, 0x7c, 0x7d, 0xf6, 0x18, 0x60,

0x20, 0x00, 0x36, 0x78, 0xfd, 0xf6, 0xfb, 0xe0, 0x20, 0x00, 0x77, 0x39, 0xfd, 0xf6, 0xfb, 0xe8,

0x30, 0x00, 0x77, 0x33, 0xfc, 0xe6, 0xfb, 0xc8, 0x30, 0x00, 0xf7, 0x90, 0x7e, 0x1e, 0xfb, 0xc8,

0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xcc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0xe7, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x78,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8

};

static const unsigned char PROGMEM bitmap2N[] =

{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,

0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x98, 0x83, 0xe1, 0xc0, 0x7c, 0x66, 0x0f, 0xff, 0x88,

0x03, 0x33, 0x60, 0xc6, 0x66, 0x1f, 0xff, 0xc8, 0x03, 0x10, 0x20, 0xc6, 0x76, 0x1f, 0xff, 0xc0,

0x03, 0x30, 0x61, 0x83, 0x76, 0x1f, 0xff, 0xc0, 0x03, 0xe0, 0xe1, 0x83, 0x7e, 0x1f, 0xff, 0xc0,

0x03, 0x61, 0xc1, 0x83, 0x6e, 0x1f, 0xff, 0xc0, 0x03, 0x33, 0x80, 0xc6, 0x6e, 0x1f, 0xff, 0xc8,

0x03, 0x33, 0x00, 0xc6, 0x66, 0x0f, 0xff, 0xc8, 0x83, 0x1f, 0xe0, 0x7c, 0x66, 0x0f, 0xff, 0x88,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x38,

0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,

0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8

};

static const unsigned char PROGMEM bitmap3F[] =

{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8,

0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xe7, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78,

0xce, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0x90, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x30, 0x00, 0x70, 0x78, 0xfe, 0x1e, 0x18, 0x48,

0x20, 0x00, 0x37, 0x32, 0x7c, 0xe6, 0xfb, 0xe0, 0x20, 0x00, 0x37, 0xbe, 0x7d, 0xf6, 0xfb, 0xe0,

0x20, 0x00, 0x37, 0x3c, 0xfd, 0xf6, 0xfb, 0xe0, 0x20, 0x00, 0x30, 0x7e, 0x7d, 0xf6, 0x18, 0x60,

0x20, 0x00, 0x36, 0x7f, 0x7d, 0xf6, 0xfb, 0xe0, 0x20, 0x00, 0x77, 0x3f, 0x7d, 0xf6, 0xfb, 0xe8,

0x30, 0x00, 0x77, 0x36, 0x7c, 0xe6, 0xfb, 0xc8, 0x30, 0x00, 0xf7, 0x98, 0xfe, 0x1e, 0xfb, 0xc8,

0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xcc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0xe7, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x78,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8

};

static const unsigned char PROGMEM bitmap3N[] =

{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,

0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x98, 0x83, 0xe1, 0xc0, 0x7c, 0x66, 0x0f, 0xff, 0x88,

0x03, 0x33, 0x60, 0xc6, 0x66, 0x1f, 0xff, 0xc8, 0x03, 0x10, 0x60, 0xc6, 0x76, 0x1f, 0xff, 0xc0,

0x03, 0x30, 0xc1, 0x83, 0x76, 0x1f, 0xff, 0xc0, 0x03, 0xe0, 0x61, 0x83, 0x7e, 0x1f, 0xff, 0xc0,

0x03, 0x60, 0x21, 0x83, 0x6e, 0x1f, 0xff, 0xc0, 0x03, 0x30, 0x20, 0xc6, 0x6e, 0x1f, 0xff, 0xc8,

0x03, 0x33, 0x60, 0xc6, 0x66, 0x0f, 0xff, 0xc8, 0x83, 0x19, 0xc0, 0x7c, 0x66, 0x0f, 0xff, 0x88,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x38,

0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,

0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8

};

static const unsigned char PROGMEM bitmap4F[] =

{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8,

0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xe7, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78,

0xce, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0x90, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x30, 0x00, 0x70, 0x7e, 0xfe, 0x1e, 0x18, 0x48,

0x20, 0x00, 0x37, 0x3c, 0xfc, 0xe6, 0xfb, 0xe0, 0x20, 0x00, 0x37, 0xbc, 0xfd, 0xf6, 0xfb, 0xe0,

0x20, 0x00, 0x37, 0x38, 0xfd, 0xf6, 0xfb, 0xe0, 0x20, 0x00, 0x30, 0x72, 0xfd, 0xf6, 0x18, 0x60,

0x20, 0x00, 0x36, 0x76, 0xfd, 0xf6, 0xfb, 0xe0, 0x20, 0x00, 0x77, 0x20, 0x3d, 0xf6, 0xfb, 0xe8,

0x30, 0x00, 0x77, 0x3e, 0xfc, 0xe6, 0xfb, 0xc8, 0x30, 0x00, 0xf7, 0x9e, 0xfe, 0x1e, 0xfb, 0xc8,

0x98, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xcc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98,

0xe7, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x78,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8

};

static const unsigned char PROGMEM bitmap4N[] =

{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8,

0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,

0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18,

0x83, 0xe0, 0x60, 0x7c, 0x66, 0x07, 0xff, 0x98, 0x83, 0x30, 0xe0, 0xc6, 0x66, 0x0f, 0xff, 0x88,

0x03, 0x11, 0xe0, 0xc6, 0x76, 0x1f, 0xff, 0xc8, 0x03, 0x31, 0xe1, 0x83, 0x76, 0x1f, 0xff, 0xc0,

0x03, 0xe3, 0x61, 0x83, 0x7e, 0x1f, 0xff, 0xc0, 0x03, 0x66, 0x61, 0x83, 0x6e, 0x1f, 0xff, 0xc0,

0x03, 0x37, 0xf0, 0xc6, 0x6e, 0x1f, 0xff, 0xc0, 0x03, 0x30, 0x60, 0xc6, 0x66, 0x1f, 0xff, 0xc8,

0x03, 0x18, 0x60, 0x7c, 0x66, 0x0f, 0xff, 0xc8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x88,

0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x18, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x38,

0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,

0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8

};

/************************************************/


void setup() {

Serial.begin(115200);

pinMode(RELAY1Pin, OUTPUT);

pinMode(RELAY2Pin, OUTPUT);

pinMode(RELAY3Pin, OUTPUT);

pinMode(RELAY4Pin, OUTPUT);

// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally

if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64

Serial.println(F("SSD1306 allocation failed"));

for (;;); // Don't proceed, loop forever

}

// Clear the buffer

display.clearDisplay();

// Invert and restore display, pausing in-between

display.invertDisplay(true);


Serial.println("Connecting to ");

Serial.println(ssid);


//connect to your local wi-fi network

WiFi.begin(ssid, password);


//check wi-fi is connected to wi-fi network

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

delay(1000);

Serial.print(".");

}

Serial.println("");

Serial.println("WiFi connected..!");

Serial.print("Got IP: "); Serial.println(WiFi.localIP());


server.on("/", handleRoot);

server.on("/toggleLED1", updateRELAY1);

server.on("/toggleLED2", updateRELAY2);

server.on("/toggleLED3", updateRELAY3);

server.on("/toggleLED4", updateRELAY4);

server.onNotFound(handleNotFound);


server.begin();

Serial.println("HTTP server started");

}

void loop() {

server.handleClient();

display.clearDisplay();

display.invertDisplay(true);

display.setTextSize(1); // Draw 2X-scale text

display.setTextColor(SSD1306_WHITE);

display.setCursor(2, 2);

display.println(WiFi.localIP());

display.display(); // Show initial text

if ((digitalRead(RELAY1Pin)) == 0)

{

display.drawBitmap(2, 18, bitmap1N, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY1Pin)) == 1)

{

display.drawBitmap(2, 18, bitmap1F, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY2Pin)) == 0)

{

display.drawBitmap(63, 18, bitmap2N, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY2Pin)) == 1)

{

display.drawBitmap(63, 18, bitmap2F, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY3Pin)) == 0)

{

display.drawBitmap(2, 40, bitmap3N, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY3Pin)) == 1)

{

display.clearDisplay();

display.drawBitmap(2, 40, bitmap3F, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY4Pin)) == 0)

{

display.drawBitmap(63, 40, bitmap4N, bitmap_height, bitmap_width, WHITE);

display.display();

}

if ((digitalRead(RELAY4Pin)) == 1)

{

display.drawBitmap(63, 40, bitmap4F, bitmap_height, bitmap_width, WHITE);

display.display();

}

delay(1000);

}


void handleRoot() {

server.send(200, "text/html", prepareHTML());

}


void updateRELAY1() {

String LED1StatusParam = server.arg("LED1Status");

if (LED1StatusParam == "OFF")

RELAY1Status = HIGH;

else

RELAY1Status = LOW;

digitalWrite(RELAY1Pin, RELAY1Status);


server.send(200, "text/plain", "Success!");

}


void updateRELAY2() {

String LED2StatusParam = server.arg("LED2Status");

if (LED2StatusParam == "OFF")

RELAY2Status = HIGH;

else

RELAY2Status = LOW;

digitalWrite(RELAY2Pin, RELAY2Status);


server.send(200, "text/plain", "Success!");

}


void updateRELAY3() {

String LED3StatusParam = server.arg("LED3Status");

if (LED3StatusParam == "OFF")

RELAY3Status = HIGH;

else

RELAY3Status = LOW;

digitalWrite(RELAY3Pin, RELAY3Status);


server.send(200, "text/plain", "Success!");

}


void updateRELAY4() {

String LED4StatusParam = server.arg("LED4Status");

if (LED4StatusParam == "OFF")

RELAY4Status = HIGH;

else

RELAY4Status = LOW;

digitalWrite(RELAY4Pin, RELAY4Status);


server.send(200, "text/plain", "Success!");

}


void handleNotFound() {

server.send(404, "text/plain", "Not found");

}


String prepareHTML() {

// BuildMyString.com generated code. Please enjoy your string responsibly.


String html = "<!DOCTYPE html>\n"

"<html>\n"

" <head>\n"

" <meta charset=\"UTF-8\">\n"

" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"

" <title>NodeMCU ESP8266 Web Server with OLED</title>\n"

" <style>\n"

" /* Copyright 2014 Owen Versteeg; MIT licensed */body,textarea,input,select{background:0;border-radius:0;font:16px sans-serif;margin:0}.smooth{transition:all .2s}.btn,.nav a{text-decoration:none}.container{margin:0 20px;width:auto}label>*{display:inline}form>*{display:block;margin-bottom:10px}.btn{background:#999;border-radius:6px;border:0;color:#fff;cursor:pointer;display:inline-block;margin:2px 0;padding:12px 30px 14px}.btn:hover{background:#888}.btn:active,.btn:focus{background:#777}.btn-a{background:#0ae}.btn-a:hover{background:#09d}.btn-a:active,.btn-a:focus{background:#08b}.btn-b{background:#3c5}.btn-b:hover{background:#2b4}.btn-b:active,.btn-b:focus{background:#2a4}.btn-c{background:#d33}.btn-c:hover{background:#c22}.btn-c:active,.btn-c:focus{background:#b22}.btn-sm{border-radius:4px;padding:10px 14px 11px}.row{margin:1% 0;overflow:auto}.col{float:left}.table,.c12{width:100%}.c11{width:91.66%}.c10{width:83.33%}.c9{width:75%}.c8{width:66.66%}.c7{width:58.33%}.c6{width:50%}.c5{width:41.66%}.c4{width:33.33%}.c3{width:25%}.c2{width:16.66%}.c1{width:8.33%}h1{font-size:3em}.btn,h2{font-size:2em}.ico{font:33px Arial Unicode MS,Lucida Sans Unicode}.addon,.btn-sm,.nav,textarea,input,select{outline:0;font-size:14px}textarea,input,select{padding:8px;border:1px solid #ccc}textarea:focus,input:focus,select:focus{border-color:#5ab}textarea,input[type=text]{-webkit-appearance:none;width:13em}.addon{padding:8px 12px;box-shadow:0 0 0 1px #ccc}.nav,.nav .current,.nav a:hover{background:#000;color:#fff}.nav{height:24px;padding:11px 0 15px}.nav a{color:#aaa;padding-right:1em;position:relative;top:-1px}.nav .pagename{font-size:22px;top:1px}.btn.btn-close{background:#000;float:right;font-size:25px;margin:-54px 7px;display:none}@media(min-width:1310px){.container{margin:auto;width:1270px}}@media(max-width:870px){.row .col{width:100%}}@media(max-width:500px){.btn.btn-close{display:block}.nav{overflow:hidden}.pagename{margin-top:-11px}.nav:active,.nav:focus{height:auto}.nav div:before{background:#000;border-bottom:10px double;border-top:3px solid;content:'';float:right;height:4px;position:relative;right:3px;top:14px;width:20px}.nav a{padding:.5em 0;display:block;width:50%}}.table th,.table td{padding:.5em;text-align:left}.table tbody>:nth-child(2n-1){background:#ddd}.msg{padding:1.5em;background:#def;border-left:5px solid #59d}\n"

" .hero {\n"

" background: #FFA500;\n"

" padding: 20px;\n"

" border-radius: 10px;\n"

" margin-top: 1em;\n"

" }\n"

" .hero h1 {\n"

" margin-top: 0;\n"

" margin-bottom: 0.3em;\n"

" }\n"

" .c4 {\n"

" padding: 10px;\n"

" box-sizing: border-box;\n"

" }\n"

" .c4 h3 {\n"

" margin-top: 0;\n"

" }\n"

" \n"

" // Code from https://proto.io/freebies/onoff/\n"

" .c4 a {\n"

" margin-top: 10px;\n"

" display: inline-block;\n"

" }\n"

" \n"

" .onoffswitch {\n"

" position: relative; width: 90px;\n"

" -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;\n"

" }\n"

" .onoffswitch-checkbox {\n"

" position: absolute;\n"

" opacity: 0;\n"

" pointer-events: none;\n"

" }\n"

" .onoffswitch-label {\n"

" display: block; overflow: hidden; cursor: pointer;\n"

" border: 2px solid #00000; border-radius: 20px;\n"

" }\n"

" .onoffswitch-inner {\n"

" display: block; width: 200%; margin-left: -100%;\n"

" transition: margin 0.3s ease-in 0s;\n"

" }\n"

" .onoffswitch-inner:before, .onoffswitch-inner:after {\n"

" display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;\n"

" font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;\n"

" box-sizing: border-box;\n"

" }\n"

" .onoffswitch-inner:before {\n"

" content: \"ON\";\n"

" padding-left: 10px;\n"

" background-color: #00FF00; color: #FFFFFF;\n"

" }\n"

" .onoffswitch-inner:after {\n"

" content: \"OFF\";\n"

" padding-right: 10px;\n"

" background-color: #FFFFFF; color: #050202;\n"

" text-align: right;\n"

" }\n"

" .onoffswitch-switch {\n"

" display: block; width: 18px; margin: 6px;\n"

" background: #FFFFFF;\n"

" position: absolute; top: 0; bottom: 0;\n"

" right: 56px;\n"

" border: 2px solid #0D0B0B; border-radius: 20px;\n"

" transition: all 0.3s ease-in 0s; \n"

" }\n"

" .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {\n"

" margin-left: 0;\n"

" }\n"

" .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {\n"

" right: 0px; \n"

" }\n"

" \n"

" .grid-container {\n"

" display: grid;\n"

" grid-template-columns: 1fr 1fr;\n"

" grid-gap: 20px;\n"

" }\n"

" \n"

" .flex-container {\n"

" display: flex;\n"

" margin-top: 40px;\n"

" }\n"

" .flex-child {\n"

" flex: 1;\n"

" //border: 2px solid yellow;\n"

" } \n"

" .flex-child:first-child {\n"

" margin-right: 20px;\n"

" } \n"

" \n"

" .component-label{\n"

" float: right;\n"

" font-weight: bold;\n"

" font-size: 25px;\n"

" }\n"

" </style>\n"

" </head>\n"

" <body>\n"

" <nav class=\"nav\" tabindex=\"-1\" onclick=\"this.focus()\">\n"

" <div class=\"container\">\n"

" <a class=\"pagename current\" href=\"#\">NodeMCU ESP8266 Web Server Relay Control with OLED Display</a>\n"

" </div>\n"

" </nav>\n"

"\n"

" <div class=\"container\">\n"

" <div class=\"hero\">\n"

" <h1>WIFI Control Relay Panel</h1>\n"

" <div class=\"flex-container\">\n"

" <div class=\"flex-child magenta\">\n"

" <span class=\"component-label\">RELAY1</span>\n"

" </div>\n"

" <div class=\"flex-child green\">\n"

" <div class=\"grid-child green\">\n"

" <div style=\"display: inline\">\n"

" <div class=\"onoffswitch\">\n"

" <input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"Relay1Switch\" tabindex=\"0\">\n"

" <label class=\"onoffswitch-label\" for=\"Relay1Switch\">\n"

" <span class=\"onoffswitch-inner\"></span>\n"

" <span class=\"onoffswitch-switch\"></span>\n"

" </label>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" <div class=\"flex-container\">\n"

" <div class=\"flex-child magenta\">\n"

" <span class=\"component-label\">RELAY2</span>\n"

" </div>\n"

" <div class=\"flex-child green\">\n"

" <div class=\"grid-child green\">\n"

" <div style=\"display: inline\">\n"

" <div class=\"onoffswitch\">\n"

" <input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"Relay2Switch\" tabindex=\"0\">\n"

" <label class=\"onoffswitch-label\" for=\"Relay2Switch\">\n"

" <span class=\"onoffswitch-inner\"></span>\n"

" <span class=\"onoffswitch-switch\"></span>\n"

" </label>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" <div class=\"flex-container\">\n"

" <div class=\"flex-child magenta\">\n"

" <span class=\"component-label\">RELAY3</span>\n"

" </div>\n"

" <div class=\"flex-child green\">\n"

" <div class=\"grid-child green\">\n"

" <div style=\"display: inline\">\n"

" <div class=\"onoffswitch\">\n"

" <input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"Relay3Switch\" tabindex=\"0\">\n"

" <label class=\"onoffswitch-label\" for=\"Relay3Switch\">\n"

" <span class=\"onoffswitch-inner\"></span>\n"

" <span class=\"onoffswitch-switch\"></span>\n"

" </label>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" <div class=\"flex-container\">\n"

" <div class=\"flex-child magenta\">\n"

" <span class=\"component-label\">RELAY4</span>\n"

" </div>\n"

" <div class=\"flex-child green\">\n"

" <div class=\"grid-child green\">\n"

" <div style=\"display: inline\">\n"

" <div class=\"onoffswitch\">\n"

" <input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"Relay4Switch\" tabindex=\"0\">\n"

" <label class=\"onoffswitch-label\" for=\"Relay4Switch\">\n"

" <span class=\"onoffswitch-inner\"></span>\n"

" <span class=\"onoffswitch-switch\"></span>\n"

" </label>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" </div>\n"

" <script>\n"

" document.getElementById('Relay1Switch').onclick = function() {\n"

" // access properties using this keyword\n"

" var LED1Status;\n"

" if ( this.checked ) {\n"

" LED1Status = \"ON\";\n"

" } else {\n"

" LED1Status = \"OFF\";\n"

" }\n"

" var xhttp = new XMLHttpRequest();\n"

" xhttp.onreadystatechange = function() {\n"

" if (this.readyState == 4 && this.status == 200) {\n"

" console.log(\"Successfully received \");\n"

" }\n"

" };\n"

" xhttp.open(\"GET\", \"toggleLED1?LED1Status=\"+LED1Status, true);\n"

" xhttp.send();\n"

" };\n"

" document.getElementById('Relay2Switch').onclick = function() {\n"

" // access properties using this keyword\n"

" var LED2Status;\n"

" if ( this.checked ) {\n"

" LED2Status = \"ON\";\n"

" } else {\n"

" LED2Status = \"OFF\";\n"

" }\n"

" var xhttp = new XMLHttpRequest();\n"

" xhttp.onreadystatechange = function() {\n"

" if (this.readyState == 4 && this.status == 200) {\n"

" console.log(\"Successfully received \");\n"

" }\n"

" };\n"

" xhttp.open(\"GET\", \"toggleLED2?LED2Status=\"+LED2Status, true);\n"

" xhttp.send();\n"

" };\n"

" document.getElementById('Relay3Switch').onclick = function() {\n"

" // access properties using this keyword\n"

" var LED3Status;\n"

" if ( this.checked ) {\n"

" LED3Status = \"ON\";\n"

" } else {\n"

" LED3Status = \"OFF\";\n"

" }\n"

" var xhttp = new XMLHttpRequest();\n"

" xhttp.onreadystatechange = function() {\n"

" if (this.readyState == 4 && this.status == 200) {\n"

" console.log(\"Successfully received \");\n"

" }\n"

" };\n"

" xhttp.open(\"GET\", \"toggleLED3?LED3Status=\"+LED3Status, true);\n"

" xhttp.send();\n"

" };\n"

" document.getElementById('Relay4Switch').onclick = function() {\n"

" // access properties using this keyword\n"

" var LED4Status;\n"

" if ( this.checked ) {\n"

" LED4Status = \"ON\";\n"

" } else {\n"

" LED4Status = \"OFF\";\n"

" }\n"

" var xhttp = new XMLHttpRequest();\n"

" xhttp.onreadystatechange = function() {\n"

" if (this.readyState == 4 && this.status == 200) {\n"

" console.log(\"Successfully received \");\n"

" }\n"

" };\n"

" xhttp.open(\"GET\", \"toggleLED4?LED4Status=\"+LED4Status, true);\n"

" xhttp.send();\n"

" };\n"

" </script>\n"

" </body>\n"

"</html>\n";



return html;

}

After a successful upload, open the Serial Monitor at a baud rate of 115200. Press the “EN/RST” button on the ESP8266 board. Now it should print its IP address.

Now open webpage and it's address shown on OLED display.


Demo






Commenti


bottom of page