In this tutorial, you’ll learn how to set your ESP8266 NodeMCU as an Access Point (AP) using Arduino IDE. This allows you to connect directly to your ESP8266 via Wi-Fi without a wireless router.

To set the ESP8266 as an Access Point use WiFi.softAP(ssid, password);
ESP8266 Station and Access Point
In most of our ESP8266 NodeMCU web server projects, we connect the ESP8266 to a wireless router. In this configuration, we can access the ESP8266 through the local network.
In this scenario, the router acts as an access point and the ESP8266 is set as a station. So, you need to be connected to your router (local network) to control the ESP8266.

In some cases, this might not be the best configuration (when you don’t have a router nearby). But if you set the ESP8266 as an access point (hotspot), you can be connected to the ESP8266 using any device with Wi-Fi capabilities without the need to connect to your router.

In simple words, when you set the ESP8266 as an access point you create its own Wi‑Fi network and nearby Wi-Fi devices (stations) can connect to it (like your smartphone or your computer).
In this tutorial, we’ll show you how to set the ESP8266 as an access point in your web server projects. This way, you don’t need to be connected to a router to control your ESP8266.
Because the ESP8266 doesn’t connect further to a wired network (like your router), it is called soft-AP (soft Access Point).
This means that if you try to load libraries or use firmware from the internet, it will not work. It also doesn’t work if you try to make HTTP requests to services on the internet like publishing sensor readings to the cloud.
Installing the DHT Library for ESP8266
For this example, we’ll use a previous web server project that displays sensor readings from a DHT sensor.
Having the ESP8266 Board installed in Arduino IDE, to read from the DHT sensor, we’ll use the DHT library from Adafruit. To use this library you also need to install the Adafruit Unified Sensor library.
Follow the next steps to install those two libraries:
1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
2. Search for “DHT” on the Search box and install the DHT library from Adafruit.

3. After installing the DHT library from Adafruit, type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it.
After installing the libraries, restart your Arduino IDE.
ESP8266 NodeMCU Access Point (AP)
In this example, we’ll modify the ESP8266 Web Server from a previous tutorial to add access point capabilities. Here’s the project example we’ll use: ESP8266 DHT11/DHT22 Temperature and Humidity Web Server with Arduino IDE.
What we’ll show you here can be used with any ESP8266 web server example.
Upload the sketch provided below to set the ESP8266 as an access point.
/*********
Welcome to Gnd_To_Vcc!!
*********/
// Import required libraries
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
const char* ssid = "ESP8266-Access-Point";
const char* password = "123456789";
#define DHTPIN 5 // Digital pin connected to the DHT sensor
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
// current temperature & humidity, updated in loop()
float t = 0.0;
float h = 0.0;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time DHT was updated
// Updates DHT readings every 10 seconds
const long interval = 10000;
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {
font-family: Arial;
display: inline-block;
margin: 0px auto;
text-align: center;
}
h2 { font-size: 3.0rem; }
p { font-size: 3.0rem; }
.units { font-size: 1.2rem; }
.dht-labels{
font-size: 1.5rem;
vertical-align:middle;
padding-bottom: 15px;
}
</style>
</head>
<body>
<h2>ESP8266 DHT Server</h2>
<p>
<span class="dht-labels">Temperature</span>
<span id="temperature">%TEMPERATURE%</span>
<sup class="units">°C</sup>
</p>
<p>
<span class="dht-labels">Humidity</span>
<span id="humidity">%HUMIDITY%</span>
<sup class="units">%</sup>
</p>
</body>
<script>
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("temperature").innerHTML = this.responseText;
}
};
xhttp.open("GET", "/temperature", true);
xhttp.send();
}, 10000 ) ;
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("humidity").innerHTML = this.responseText;
}
};
xhttp.open("GET", "/humidity", true);
xhttp.send();
}, 10000 ) ;
</script>
</html>)rawliteral";
// Replaces placeholder with DHT values
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(t);
}
else if(var == "HUMIDITY"){
return String(h);
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
dht.begin();
Serial.print("Setting AP (Access Point)…");
// Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
// Print ESP8266 Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", String(t).c_str());
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", String(h).c_str());
});
// Start server
server.begin();
}
void loop(){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you updated the DHT values
previousMillis = currentMillis;
// Read temperature as Celsius (the default)
float newT = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//float newT = dht.readTemperature(true);
// if temperature read failed, don't change t value
if (isnan(newT)) {
Serial.println("Failed to read from DHT sensor!");
}
else {
t = newT;
Serial.println(t);
}
// Read Humidity
float newH = dht.readHumidity();
// if humidity read failed, don't change h value
if (isnan(newH)) {
Serial.println("Failed to read from DHT sensor!");
}
else {
h = newH;
Serial.println(h);
}
}
}
Customize the SSID and Password
You need to define a SSID name and a password to access the ESP8266. In this example we’re setting the ESP8266 SSID name to ESP8266-Access-Point, but you can modify the name to whatever you want. The password is 123456789, but you can also modify it.
const char* ssid = "ESP8266-Access-Point";
const char* password = "123456789";
Setting the ESP8266 as an Access Point (AP)
There’s a section in the setup() to set the ESP8266 as an access point using the softAP() method:
WiFi.softAP(ssid, password);
There are also other optional parameters you can pass to the softAP() method. Here’s all the parameters:
.softAP(const char* ssid, const char* password, int channel, int ssid_hidden, int max_connection)
- ssid (defined earlier): maximum of 31 characters
- password (defined earlier): minimum of 8 characters. If not specified, the access point will be open (maximum 63 characters)
- channel: Wi-Fi channel number (1-13). Default is 1
- ssid_hidden: if set to true will hide SSID
- max_connection: max simultaneous connected stations, from 0 to 8
Next, get the access point IP address using the softAPIP() method and print it in the Serial Monitor.
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
Note: by default, the access point IP address is 192.168.4.1
These are the snippets of code you need to include in your web server sketches to set the ESP8266 as a soft access point.
To learn how the full web server code works, read: ESP8266 NodeMCU DHT11/DHT22 Temperature and Humidity Web Server with Arduino IDE.
Parts Required
To proceed with this tutorial, you need the following parts:
- ESP8266 development board.
- DHT22 or DHT11 Temperature and Humidity Sensor
- 4.7k Ohm Resistor
- Breadboard
- Jumper wires
Schematic Diagram
Assemble all the parts by following the next schematic diagram:

Connecting to the ESP8266 Access Point
Having the ESP8266 running the sketch, in your smartphone open your Wi-Fi settings and tap the ESP8266-Access-Point network:

Enter the password you’ve defined earlier.

Open your web browser and type the IP address http://192.168.4.1. The web server page should load:

The web server page is a bit different from the original web server. That web server displays two icons next to the temperature and humidity. Those icons are loaded from the Font Awesome website. However, because the ESP8266 acts a soft access point (it is not connected to the internet) we cannot load those icons.
Conclusion
In this tutorial you’ve learned how to set the ESP8266 as a soft access point. This allows you to connect to the ESP8266 web server directly via Wi-Fi without the need to connect to a router.Report this ad
However, note that the ESP8266 is not connected to the internet, so you can’t make HTTP requests to other services to publish sensor data or to get data from the internet (like loading the icons).
You may also like reading:
- ESP8266 Web Server Control Outputs
- ESP8266 Web Server using SPIFFS (SPI Flash File System) – NodeMCU
- Visualize Your Sensor Readings from Anywhere in the World (ESP32/ESP8266 + MySQL + PHP)
Thanks for reading.
2 thoughts on “ESP8266 NodeMCU Access Point (AP) for Web Server”