Arduino

ESP8266 AP & STA Mode Together (Easy Step-By-Step Tutorial)

So you are looking to create a project that requires your ESP device to work in both AP and station mode? With the Arduino ESP core it is possible to get your device to function in both AP and STA modes simultaneously and I am going to show you the secret sauce!

In this tutorial we will expand on the previous tutorial describing how to connect our ESP device to a WiFi network. As before I will be using a Wemos D1 Mini for the example, however you can use any ESP device that supports the Arduino ESP core.

Prerequisite

You will need to have the Arduino IDE installed and configured to flash ESP devices. You will also need an ESP-based board such as the Wemos D1 Mini, as this will not work with a standard Arduino board.

I would recommend that you first read my tutorial on how to configure the Arduino IDE and connect it to WiFi. The tutorial is written for the Wemos D1 Mini but it applies to any ESP-based board compatible with the Arduino ESP core.

STA mode recap

In the previous tutorial we covered how to connect our ESP device to WiFi in station (STA) mode. In this mode the ESP connects to the router as a client.

For this tutorial we will take the code from the previous tutorial and add the necessary code so that the ESP device functions in both STA and AP mode.

Ideally you should at least read through the WiFi section of the previous tutorial. However if you wish to skip over it, just create a new project in the Arduino IDE and copy and paste the following code.

#include <ESP8266WiFi.h>
 
// Set WiFi credentials
#define WIFI_SSID "YOUR WIFI NETWORK SSID"
#define WIFI_PASS "YOUR WIFI PASSWORD"
 
void setup() {
  // Setup serial port
  Serial.begin(115200);
  Serial.println();
 
  // Begin WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
 
  // Connecting to WiFi...
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  // Loop continuously while WiFi is not connected
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }
 
  // Connected to WiFi
  Serial.println();
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
 
}
 
void loop() {
  // put your main code here, to run repeatedly:
 
}

Add AP Mode

This project will connect your ESP device to a router using WIFI_SSID and WIFI_PASS. Now we can start to add the additional code to make our ESP device also appear as an access point.

Add AP credentials

First we will define an SSID and password for our access point. Go ahead and add the highlighted code to the project, you can change the SSID and password to whatever you like.

#include <ESP8266WiFi.h>
 
// Set WiFi credentials
#define WIFI_SSID "YOUR WIFI NETWORK SSID"
#define WIFI_PASS "YOUR WIFI PASSWORD"

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
 
void setup() {
  // Setup serial port
  Serial.begin(115200);
  Serial.println();
 
  // Begin WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
 
  // Connecting to WiFi...
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  // Loop continuously while WiFi is not connected
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }
 
  // Connected to WiFi
  Serial.println();
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
 
}
 
void loop() {
  // put your main code here, to run repeatedly:
 
}

Begin the access point

After we begin the serial port for receiving the information about our network in the serial console, we can begin the access point.

#include <ESP8266WiFi.h>
 
// Set WiFi credentials
#define WIFI_SSID "YOUR WIFI NETWORK SSID"
#define WIFI_PASS "YOUR WIFI PASSWORD"

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
 
void setup() {
  // Setup serial port
  Serial.begin(115200);
  Serial.println();
 
  // Begin Access Point
  WiFi.softAP(AP_SSID, AP_PASS);

  // Begin WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
 
  // Connecting to WiFi...
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  // Loop continuously while WiFi is not connected
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }
 
  // Connected to WiFi
  Serial.println();
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
 
}
 
void loop() {
  // put your main code here, to run repeatedly:
 
}

Print to the serial console

Lastly we will modify the commands that print to the serial console to include the additional information about our access point. All of the serial print commands are optional, so you can omit them if you prefer.

#include <ESP8266WiFi.h>


// Set WiFi credentials
#define WIFI_SSID "YOUR WIFI NETWORK SSID"
#define WIFI_PASS "YOUR WIFI PASSWORD"

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"

void setup()
{
  // Setup serial port
  Serial.begin(115200);
  Serial.println();

  // Begin Access Point
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP(AP_SSID, AP_PASS);

  // Begin WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  // Connecting to WiFi...
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }

  // Connected to WiFi
  Serial.println();
  Serial.println("Connected!");
  Serial.print("IP address for network ");
  Serial.print(WIFI_SSID);
  Serial.print(" : ");
  Serial.println(WiFi.localIP());
  Serial.print("IP address for network ");
  Serial.print(AP_SSID);
  Serial.print(" : ");
  Serial.print(WiFi.softAPIP());

}

void loop() {
  // put your main code here, to run repeatedly:
 
}

That’s it! Go ahead and upload the sketch and open the serial terminal. Assuming you have included the serial print command, you should see confirmation that you have successfully connected. Your STA and AP IP addresses will also be displayed.

Additional configuration

There are also some additional configuration options which we can use if necessary.

Network parameters

Firstly we can specify the desired WiFi channel for the access point between 1 and 13.

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
#define AP_CHANNEL 1

We can also specify whether or not our network should be hidden. If our network is hidden them we must know the name as well as the password in order to join it.

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
#define AP_CHANNEL 1
#define AP_HIDDEN true

Finally we can specify the maximum number of clients that can connect. This defaults to 4 and has a maximum of 8.

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
#define AP_CHANNEL 1
#define AP_HIDDEN true
#define AP_MAX_CON 8

In order to use the additional attributes, we can change our WiFi.softAP command to incorporate all of the parameters. Note that the only required parameter is AP_SSID, everything else is optional.

// Begin Access Point
WiFi.softAP(AP_SSID, AP_PASS, AP_CHANNEL, AP_HIDDEN, AP_MAX_CON);

Network interface

It is also possible to specify the local IP address, gateway and subnet mask. These must be specified using the IPAddress type.

// Set AP credentials
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
#define AP_CHANNEL 1
#define AP_HIDDEN true
#define AP_MAX_CON 8

// Set IP addresses
IPAddress local_IP(192,168,4,22);
IPAddress gateway(192,168,4,9);
IPAddress subnet(255,255,255,0);

In order to use them we must add an additional configuration line before we begin the access point.

// Begin Access Point
WiFi.softAPConfig(local_IP, gateway, subnet);
WiFi.softAP(AP_SSID, AP_PASS, AP_CHANNEL, AP_HIDDEN, AP_MAX_CON);

Manage the network

There are some additional useful tools within the WiFi library that may be useful in your application. For example, we can return the number of stations that are connected to the access point with the following.

WiFi.softAPgetStationNum()

We can also disconnect any connected stations using the following.

WiFi.softAPdisconnect(wifioff)

It is also possible to fetch the MAC address from memory. This is done by creating a 6 element uint8_t and using the function to save the value of the MAC address into this variable.

uint8_t macAddr[6];
WiFi.softAPmacAddress(macAddr);
Serial.printf("MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);

Conclusion

In this tutorial we have expanded on the basic ESP station configuration and added the ability to generate an access point. The ESP Arduino library makes this very simple and is a great tool for makers!

The topics in this tutorial should provide enough basic information for you to incorporate either STA and/or AP modes into your project! Why not go ahead and check out some more of my ESP device tutorials!

back to top