ESP32 (6) – How to connect to a wifi network

by luca

In this post I’m going to show you how to connect to a wifi network.

The esp-idf framework includes a wifi driver that manages the wifi interface of the esp32 chip. The driver exposes API calls the programmer can use to interact with it; you’ve already used some of those APIs in my previous tutorial:


The driver is executed in parallel with the main program and communicates with it using events:


In the main program you have to define a function that will be the event handler, i.e. a function called by the wifi driver every time it has to notify a new event:

static esp_err_t event_handler(void *ctx, system_event_t *event)

then you have to tell the framework the name of your function:

ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

The list of the events the framework may generate is included in the esp_event.h file. The events related to the wifi driver when working in station mode have SYSTEM_EVENT_STA as name prefix:


The connection to a wifi network follows this flow diagram:


  • the main program configures and starts the driver via API calls
  • after having completed its internal tasks, the driver notifies that it has successfully started triggering the event SYSTEM_EVENT_STA_START
  • the event handler, once received that event, can call the esp_wifi_connect() API to ask the driver to connect to the network specified during the configuration phase
  • when the connection is completed and after having obtained a valid IP address (if the DHCP service is used), the driver triggers the event SYSTEM_EVENT_STA_GOT_IP
  • now the event handler can inform the main program that the connection has been completed

Tasks synchronization

In the process described above, the main program waits for the connection to be completed before executing its own instructions. It’s therefore important to understand how to synchronize the different elements: the main program, the event handler and the wifi driver. FreeRTOS offers different ways to make the tasks communicate: one of the simplest is via events. Events, in FreeRTOS, are managed using event groups and event bits.

Event bits are similar to flags,  visible to the different tasks:

  • the programmer can create as many event bits as he needs
  • tasks can activate (set) o deactivate (clear) the different bits
  • a task can pause its execution waiting for one of more bits to be set

Event bits are grouped into event groups, each of them usually contains 8 event bits. Event bits in an event group are numbered depending on their “position” (BIT0, BIT1…):


The program

The complete program is available in my Github repository. Let’s review the main sections:

static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
wifi_event_group = xEventGroupCreate();

The program defines an event group (wifi_event_group) and an event bit (CONNECTED_BIT). In the app_main() the event group is created using the FreeRTOS xEventGroupCreate() method.

wifi_config_t wifi_config = {
  .sta = {
    .ssid = WIFI_SSID,
    .password = WIFI_PASS,
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));

The configuration of the wifi network starts with the definition of two constants: the SSID name and the password (WIFI_SSID e WIFI_PASS). The constants are then used to initialize the wifi_config struct; struct which is then passed as parameter to the esp_wifi_set_config method.

static esp_err_t event_handler(void *ctx, system_event_t *event)
switch(event->event_id) {
    xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
    xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);

The event handler manages the different events triggered by the wifi driver as explained above. In particular, once the connection is established (STA_GOT_IP event), sets the CONNECTED_BIT event bit. On the contrary, in case of disconnection it clears the same event bit.

xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);

The main task pauses its execution until the connection to the wifi network is perfomed, waiting for the CONNECTED_BIT bit to be set. The portMAX_DELAY constant will cause the task to block indefinitely (without a timeout).

tcpip_adapter_ip_info_t ip_info;
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info));
printf("IP Address:  %s\n", ip4addr_ntoa(&ip_info.ip));
printf("Subnet mask: %s\n", ip4addr_ntoa(&ip_info.netmask));
printf("Gateway:     %s\n", ip4addr_ntoa(&;

When the connection is established, the main task prints out the network parameters (IP address, netmask and gateway). The TCPIP_ADAPTER_IF_STA constant represents (see tcpip_adapter.h) the network interface of the esp32 chip when working in station mode.

Here’s a screenshot of the program in execution:


To make its output clearer, I turned off the default logging of the wifi driver with the instruction:

esp_log_level_set("wifi", ESP_LOG_NONE);

and disabled the buffering for the standard output:

setvbuf(stdout, NULL, _IONBF, 0);

Related Posts


rudi ;-) Monday January 16th, 2017 - 11:47 AM


nice post!
hope we read more of this art from you.

best wishes
rudi 😉

luca Tuesday January 17th, 2017 - 02:00 PM

Thanks Rudi, it’s great to read you here: I followed your posts on the official forum! I’m going to post a tutorial every week, a lot of peripherals in this little chip 😉

Andrew Tuesday January 17th, 2017 - 02:18 AM

Somehow your code from github doesn’t work on my ESP32. The program is simple and straightforward, thanks for all those details… but it throws ‘Guru Meditation Error of type LoadProhibited occurred on core 0. Exception was unhandled.’ My other WiFi programs work fine though.

luca Tuesday January 17th, 2017 - 01:55 PM

Hi Andew… very strange: I’ve just compiled the example again and it runs fine on my ESP32 board. Are you using the release 1.0 of the framework or is it updated with the latest commits?

lind Wednesday April 26th, 2017 - 12:07 PM

Hi, I had the same problem, commenting the line :
//setvbuf(stdout, NULL, _IONBF, 0);
solved the problem for me

luca Wednesday April 26th, 2017 - 12:57 PM

Thanks! It solved also for me… I’m going to fix all the examples in the repository

Reply – ESP32 (18) – Access Point Saturday May 20th, 2017 - 03:39 PM

[…] il chip esp32 in STAtion Mode, ovvero come client che si collega ad una rete wifi esistente. In un precedente articolo ho spiegato in dettaglio come interagiscono i vari componenti del framework esp-idf per […]

Rodolfo Wednesday May 24th, 2017 - 01:46 PM

Hello Luca,

Thank for your guides! I’m planning to follow them all 🙂

I’m having a problem with this one. I downloaded your code from Github and I have the following errors:

const int CONNECTED_BIT = BIT0; // BIT0 could not be resolved

tcpip_adapter_ip_info_t ip_info; // tcpip_adapter_ip_info_t could not be resolved

I tried including #include “tcpip_adapter.h” (Path and Symbols, GNU C, add the folder tcpip_adapter under components) and adding a #include “tcpip_adapter.h” in the main. But the include is also not resolved.

I tried also rebuilding the index. But still the same problem.

Any advice? Thanks!!

luca Thursday May 25th, 2017 - 03:02 PM

Hi Rodolfo, this is strange… I can compile the example with the latest framework. For example I include esp_event_loop.h, which includes esp_event.h which includes tcpip_adapter.h that defines tcpip_adapter_ip_info_t. Are you sure your esp-idf repository is updated and complete?

Rodolfo Monday May 29th, 2017 - 10:09 AM

Now it’s even stranger. I erased part of the code that was directly using tcpip functions and left esp_event_loop. Now it compiles… When seeing esp_event.h, there is a warning saying that the include is not found. But it’s not an error. I’m using the latest esp-idf on OSX. Maybe it’s a good idea to reinstall everything again. Will keep you posted. Thanks

Kartik Sikka Saturday July 22nd, 2017 - 04:59 PM

Hi luca ,
I have been reading your posts on ESP 32 , they are amazing .

I have one question that , form where do you collect the info to write the code ?

I want to write my own code for ESP 32 for some application , How do I proceed ?

luca Monday July 24th, 2017 - 09:15 AM

Hi, my sources are the official documentation, the official forum ( and many tutorials/videos other makers publish everyday on the Internet!

Emilio Friday September 15th, 2017 - 09:23 AM

congrats for the great job and your dedication to this!!
I guess the code should compile using Arduino IDE, if so, it halts in setup() at “configure the wifi connection and start the interface” with error: C99 designator ‘ssid’ outside aggregate initializer.
The only thing I did is copy/paste in the IDE added void loop() and changed the main to setup().
Is it correct?
Thanks again.

luca Saturday September 16th, 2017 - 03:58 PM

Hi Emilio, this code (and in general my tutorials) are not meant to be used with Arduino IDE but with the official esp-idf framework.

Reply – ESP32lights Monday January 8th, 2018 - 09:12 AM

[…] il collegamento ad una rete wifi e l’utilizzo dei pin digitali del chip esp32 per il controllo del relay sono stati oggetto […]

Stefano Monday February 12th, 2018 - 04:13 PM

Ciao Luca, per iniziare ti faccio i complimenti per il grande lavoro che hai fatto.
Ho un modulo ESP-WROOM-32 sul quale ho provato un po’ di esempi dell’ambiente ESP-IDF e funzionano.
Ho provato a compilare il tuo esempio sulla connessione wifi, ma appena riavvio l’esp dopo l’upload, sul monitor vedo a rotazione sempre questi messaggi:

luca Monday February 26th, 2018 - 02:54 PM

ciao Stefano, ho rivisto recentemente tutti i sorgenti per renderli compatibili con le nuove versioni di esp-idf… prova nuovamente prendendo l’esempio da Github

Stefano Tuesday February 13th, 2018 - 09:50 PM

Alla fine ho cambiato modulo e quest’ultimo funziona.
Dovrò approfondire perchè l’altro da quei problemi

Ivan Saturday October 6th, 2018 - 09:46 PM

Ciao Luca,
mi spieghi la necessità di
while (1)
vTaskDelay(1000 / portTICK_RATE_MS);

in mai_task, ho provato a toglierlo, ma non si collega più alla rete wifi. Non capisco il perchè.


luca Monday October 8th, 2018 - 07:15 AM

ciao, serve per mettere in “pausa” quel task in modo che FreeRTOS possa eseguire anche gli altri tasks del programma, tra i quali quello che si occupa proprio della connessione wifi


Leave a Comment

fifteen + eighteen =