
What You’ll Learn
This guide explains how to turn your ESP32 into a WiFi hotspot (Access Point) that other devices can connect to. We’ll break down every single line of code so you understand exactly what’s happening.
What is Access Point Mode?
Think of your ESP32 as a mini WiFi router. When you enable AP mode:
- ESP32 creates a WiFi network (like “ESP32_AccessPoint”)
- Your phone/laptop can connect to it (just like connecting to any WiFi)
- Devices can communicate with ESP32 (no internet needed!)
Real-world analogy: Your home WiFi router creates a network called “Home-WiFi-123”. Your ESP32 does the same thing, but it’s much smaller and programmable!
Before We Start: What You Need to Know
Required Includes (Libraries)
These are like importing tools you need:
#include "esp_wifi.h" // WiFi functions (connect, create AP, etc.) #include "esp_event.h" // Event handling (device connected/disconnected) #include "esp_log.h" // Logging/printing messages #include "nvs_flash.h" // Non-volatile storage (save settings) #include "esp_netif.h" // Network interface (IP addresses, DHCP)
Think of it like: Before building a house, you gather tools (hammer, saw, etc.). These #include statements gather the programming tools we need.
The Complete Code with Explanations
Let’s break down the example piece by piece:
Step 1: Configuration Defines
#define EXAMPLE_ESP_WIFI_SSID "ESP32_AccessPoint" #define EXAMPLE_ESP_WIFI_PASS "mypassword123" #define EXAMPLE_ESP_WIFI_CHANNEL 1 #define EXAMPLE_MAX_STA_CONN 4
What this means:
EXAMPLE_ESP_WIFI_SSID= The WiFi network name people will see- Like seeing “Starbucks WiFi” on your phone, you’ll see “ESP32_AccessPoint”
EXAMPLE_ESP_WIFI_PASS= The password to connect- Must be at least 8 characters long
- If empty (“”), the network will be OPEN (no password)
EXAMPLE_ESP_WIFI_CHANNEL= WiFi channel (1-13)- Think of it like radio stations (FM 101.5, 102.3, etc.)
- Channel 1 is usually fine
EXAMPLE_MAX_STA_CONN= Maximum devices that can connect- STA = “Station” (a device connecting to your AP)
- 4 means up to 4 phones/laptops can connect at once
Step 2: Create a Tag for Logging
static const char *TAG = "wifi_ap";
What this means:
- This is like putting a label on your messages
- When ESP32 prints something, it will say:
[wifi_ap] Your message here - Helps you identify where messages come from in larger programs
The static const char * part:
static= Only visible in this fileconst= Cannot be changedchar *= Pointer to text (a string)
Step 3: Event Handler Function
This is where things get interesting!
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
ESP_LOGI(TAG, "Station "MACSTR" joined, AID=%d",
MAC2STR(event->mac), event->aid);
} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
ESP_LOGI(TAG, "Station "MACSTR" left, AID=%d",
MAC2STR(event->mac), event->aid);
}
}
What is an Event Handler?
Think of it like a doorbell:
- When someone rings your doorbell (event happens)
- You go check who it is (event handler runs)
- You react accordingly (print message, do something)
Breaking it Down:
Function Parameters:
void* arg // Extra arguments (we don't use this) esp_event_base_t event_base // What type of event (WiFi, Bluetooth, etc.) int32_t event_id // Specific event (connected, disconnected) void* event_data // Data about the event (who connected, their MAC address)
What Happens When Someone Connects:
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
- This checks: “Did someone just connect to my AP?”
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
- Get the connection details (who connected?)
- This is like looking through the peephole to see who rang the doorbell
ESP_LOGI(TAG, "Station "MACSTR" joined, AID=%d",
MAC2STR(event->mac), event->aid);
- ESP_LOGI = Print an INFO level message
- MACSTR = Placeholder for MAC address format
- MAC2STR(event->mac) = Convert MAC address to readable text
- event->aid = “Association ID” – a unique number for this connection (1, 2, 3, 4…)
Output looks like:
[wifi_ap] Station 12:34:56:78:9a:bc joined, AID=1
MAC Address: Every device has a unique MAC address (like a hardware serial number). Example: 12:34:56:78:9a:bc
What Happens When Someone Disconnects:
Same idea, but for disconnection:
else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
// Print who left
}
Step 4: The Main WiFi Initialization Function
This is the heart of the program! Let’s go line by line:
void wifi_init_softap(void)
{
“softap” = Software Access Point (AP created by software, not hardware router)
Part A: Initialize Network Interface
ESP_ERROR_CHECK(esp_netif_init());
What this does:
- Initializes the network system
- Like turning on the WiFi chip in your ESP32
- ESP_ERROR_CHECK = If there’s an error, the program stops and tells you
Think of it like: Turning on your car before driving. You can’t drive without starting the engine first.
ESP_ERROR_CHECK(esp_event_loop_create_default());
What this does:
- Creates the event system (the “doorbell” system we talked about)
- Now ESP32 can detect and handle events (connections, disconnections)
esp_netif_create_default_wifi_ap();
What this does:
- Creates a network interface specifically for AP mode
- Sets up default IP addresses (192.168.4.1)
- Sets up DHCP server (gives IP addresses to connected devices)
DHCP = Dynamic Host Configuration Protocol
- Simple explanation: Automatically gives IP addresses to devices
- When your phone connects, DHCP gives it an IP like 192.168.4.2
Part B: Initialize WiFi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg));
What this does:
WIFI_INIT_CONFIG_DEFAULT()= Get default WiFi settingsesp_wifi_init(&cfg)= Initialize WiFi with those settings
Think of it like: Installing WiFi drivers on your computer. You need to set up the WiFi hardware before using it.
Part C: Register Event Handler
ESP_ERROR_CHECK(esp_event_handler_instance_register(
WIFI_EVENT, // Listen for WiFi events
ESP_EVENT_ANY_ID, // Listen for ANY WiFi event
&wifi_event_handler, // Call this function when events happen
NULL, // No extra arguments
NULL // Don't save the handler instance
));
What this does:
- Connects your event handler function to the event system
- Now when someone connects/disconnects,
wifi_event_handlerwill be called
Real-world analogy: You tell the doorbell system “When someone rings, call me at this phone number”
Part D: Configure AP Settings
This is where we actually set up our WiFi network!
wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.password = EXAMPLE_ESP_WIFI_PASS,
.max_connection = EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.required = false,
},
},
};
Let’s break down each setting:
wifi_config_t wifi_config = {
- Create a configuration structure
- Think of it like filling out a form with all your WiFi settings
.ap = {
- We’re configuring the Access Point (AP) part
.ssid = EXAMPLE_ESP_WIFI_SSID,
- SSID = Service Set Identifier (the WiFi network name)
- This will be “ESP32_AccessPoint”
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
- Length of the SSID name in characters
strlen()= STRing LENgth function- “ESP32_AccessPoint” = 18 characters
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
- WiFi channel (we set it to 1)
- Valid range: 1-13 (depending on country)
.password = EXAMPLE_ESP_WIFI_PASS,
- The WiFi password
- Must be 8-63 characters for WPA2
.max_connection = EXAMPLE_MAX_STA_CONN,
- Maximum number of devices that can connect (4)
.authmode = WIFI_AUTH_WPA2_PSK,
- Authentication mode = How secure is your network
- WPA2_PSK = WiFi Protected Access 2 with Pre-Shared Key
- This is the most common security (same as your home WiFi)
Security options:
WIFI_AUTH_OPEN= No password (anyone can connect)WIFI_AUTH_WPA_PSK= WPA securityWIFI_AUTH_WPA2_PSK= WPA2 security (recommended)WIFI_AUTH_WPA3_PSK= WPA3 security (newest, most secure)
.pmf_cfg = {
.required = false,
},
- PMF = Protected Management Frames
- Advanced security feature (not required for basic usage)
- Set to
falsefor compatibility
Part E: Handle Open Networks
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
What this does:
- If password is empty (“”), make the network OPEN
- OPEN = No password required to connect
Why? If there’s no password, we can’t use WPA2 security, so we switch to OPEN mode.
Part F: Apply WiFi Configuration and Start
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
- Set ESP32 to Access Point mode
- Other modes:
WIFI_MODE_STA= Station mode (connect to other WiFi)WIFI_MODE_APSTA= Both AP and Station simultaneously
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
- Apply our configuration to the AP interface
WIFI_IF_AP= WiFi Interface: Access Point&wifi_config= Pointer to our configuration structure
ESP_ERROR_CHECK(esp_wifi_start());
- Start the WiFi!
- After this line, your ESP32 is broadcasting a WiFi network
- Other devices can now see and connect to it
ESP_LOGI(TAG, "WiFi AP started. SSID:%s password:%s channel:%d",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
- Print a confirmation message
- Output:
[wifi_ap] WiFi AP started. SSID:ESP32_AccessPoint password:mypassword123 channel:1
Step 5: The app_main() Function
This is where your program starts (like main() in regular C programs):
void app_main(void)
{
Initialize NVS (Non-Volatile Storage)
esp_err_t ret = nvs_flash_init();
What is NVS?
- Non-Volatile Storage = Permanent memory (like a hard drive)
- Stores data even when ESP32 is powered off
- Used to save WiFi credentials, settings, etc.
Think of it like: Formatting a USB drive before using it for the first time.
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
What this does:
- If NVS has problems (no space, or version mismatch)
- Erase everything and reinitialize
- Common pattern in ESP32 programs
Why needed? Sometimes NVS gets corrupted or full, so we clean it up.
ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); wifi_init_softap();
- Print a message saying we’re starting AP mode
- Call our WiFi initialization function
- That’s it! Your ESP32 is now a WiFi Access Point
What Happens When You Run This Code?
Step-by-Step Execution:
- ESP32 boots up →
app_main()is called - NVS is initialized → Storage system ready
- WiFi initialization starts →
wifi_init_softap()is called - Network interface created → IP address 192.168.4.1 assigned to ESP32
- Event system created → Ready to detect connections
- WiFi started → Network “ESP32_AccessPoint” is now broadcasting
- ESP32 waits → Event handler monitors for connections
When Someone Connects:
- Phone/laptop connects to “ESP32_AccessPoint”
- Event fires →
WIFI_EVENT_AP_STACONNECTED - Event handler runs → Prints “Station XX:XX:XX:XX:XX:XX joined”
- DHCP assigns IP → Connected device gets IP like 192.168.4.2
Network Details
IP Address Configuration
When ESP32 is in AP mode, it automatically configures:
ESP32 (Gateway): 192.168.4.1 Subnet Mask: 255.255.255.0 DHCP Range: 192.168.4.2 - 192.168.4.255
What this means:
- ESP32 IP: 192.168.4.1 (this is the “router” address)
- Connected devices: Get IPs like 192.168.4.2, 192.168.4.3, 192.168.4.4
- Subnet mask: Defines the network range (all devices are 192.168.4.X)
How to Connect and Test
- Upload code to ESP32
- Open serial monitor (to see logs)
- On your phone/laptop:
- Open WiFi settings
- Look for network “ESP32_AccessPoint”
- Connect using password “mypassword123”
- Check serial monitor:
- You’ll see:
Station XX:XX:XX:XX:XX:XX joined, AID=1
- You’ll see:
- Open browser on phone:
- Go to http://192.168.4.1
- (Note: This basic code doesn’t serve a webpage yet!)
Common Concepts Explained
What is a MAC Address?
Example: 12:34:56:AB:CD:EF
- MAC = Media Access Control
- Unique hardware identifier for every network device
- Like a serial number for WiFi/Ethernet chips
- Format: Six pairs of hexadecimal numbers separated by colons
Your phone has one, your laptop has one, every device has one!
What is AID (Association ID)?
AID=1, AID=2, AID=3...
- AID = Association ID
- A number assigned to each connected device (1, 2, 3, 4…)
- Makes it easy to track connections
- When device disconnects, its AID can be reused
What is DHCP?
DHCP = Dynamic Host Configuration Protocol
Without DHCP (manual):
- You connect to WiFi
- You manually type: IP=192.168.4.2, Gateway=192.168.4.1
- Very annoying!
With DHCP (automatic):
- You connect to WiFi
- ESP32 automatically gives you an IP address
- Everything just works!
Static vs. Non-Static Functions
static void wifi_event_handler(...) // Can only be used in this file void wifi_init_softap(...) // Can be called from other files
- static = Private to this file (good practice for internal functions)
- non-static = Can be called from anywhere (public functions)
Data Flow Diagram
┌─────────────────────────────────────────────────────┐
│ app_main() │
│ - Initialize NVS (storage) │
│ - Call wifi_init_softap() │
└─────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ wifi_init_softap() │
│ 1. Initialize network interface │
│ 2. Create event loop │
│ 3. Create WiFi AP interface │
│ 4. Initialize WiFi │
│ 5. Register event handler │
│ 6. Configure AP settings (SSID, password, etc.) │
│ 7. Set mode to AP │
│ 8. Apply configuration │
│ 9. Start WiFi │
└─────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ WiFi AP is Broadcasting │
│ Network Name: ESP32_AccessPoint │
│ Password: mypassword123 │
│ IP Address: 192.168.4.1 │
└─────────────────┬───────────────────────────────────┘
│
┌─────────┴─────────┐
│ │
▼ ▼
Device Connects Device Disconnects
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Event Handler │ │ Event Handler │
│ Prints: │ │ Prints: │
│ "Station joined" │ │ "Station left" │
└──────────────────┘ └──────────────────┘
Complete Code Summary
Here’s what each part does in simple terms:
| Code Section | What It Does | Why Important |
|---|---|---|
#define SSID, PASS | Sets network name and password | This is what users see and type |
wifi_event_handler() | Detects when devices connect/disconnect | Lets you know what’s happening |
nvs_flash_init() | Prepares storage system | Required before WiFi starts |
esp_netif_init() | Initializes network system | Required for IP addresses |
esp_event_loop_create_default() | Creates event system | Required for event handler |
esp_netif_create_default_wifi_ap() | Sets up AP network interface | Configures DHCP and default IPs |
esp_wifi_init() | Initializes WiFi hardware | Required before using WiFi |
esp_event_handler_instance_register() | Connects event handler | Makes your handler function work |
wifi_config_t | Configures WiFi settings | SSID, password, security, etc. |
esp_wifi_set_mode(WIFI_MODE_AP) | Sets ESP32 to AP mode | Makes it act like a router |
esp_wifi_set_config() | Applies your settings | Configures the WiFi with your settings |
esp_wifi_start() | Starts WiFi | Begins broadcasting network |
Troubleshooting for Beginners
“Why can’t I see the WiFi network?”
Check:
- Code uploaded successfully?
- ESP32 powered on?
- Check serial monitor for “WiFi AP started” message
- Try scanning WiFi networks again
- Make sure WiFi is enabled on your device
“Why can’t I connect?”
Check:
- Password is correct (“mypassword123”)
- Password is at least 8 characters
- Try making it an OPEN network (set password to “”)
- Check if max connections (4) is reached
“What is ESP_ERROR_CHECK()?”
- It checks if the function succeeded
- If error occurs, program stops and prints error message
- Very useful for debugging!
“Do I need internet for this?”
NO! Access Point mode works completely offline:
- ESP32 creates its own network
- Devices connect directly to ESP32
- No router needed
- No internet needed
Next Steps
After understanding this basic AP code, you can:
- Add a web server → Serve HTML pages
- Control GPIO pins → Turn LEDs on/off from phone
- Read sensors → Display temperature, humidity, etc.
- Create a configuration portal → Let users input WiFi credentials
- Add AP+STA mode → ESP32 connects to internet AND acts as AP
Key Takeaways
✅ AP mode makes ESP32 a WiFi hotspot ✅ Other devices connect to it like any WiFi network ✅ Event handlers detect connections/disconnections ✅ DHCP automatically assigns IP addresses ✅ No internet required – works standalone ✅ Can handle multiple connections
Congratulations! 🎉
You now understand how ESP32 Access Point mode works at a fundamental level. This is the foundation for building IoT projects, web servers, and configuration portals!