How to connect ESP32 to WiFi using ESP-IDF (IOT Development FrameWork)

Fateh Ali Shahrukh Khan
6 min readJul 9, 2023

--

Yes I know its example is available on esp-idf/examples/wifi/getting_started/station in your machine or on Espressif git hub but running an example alone is never sufficient until and unless you know what is happening on the back end of code or why example code is written in a specific way.

Rewriting the code from scratch provides a developer a deeper understanding about the code itself, also it provides one to customize the code and add more features such as MQTT or RTC updates or Smart WiFi Configurations (more on this on next article)

Without further ado let’s start coding :)

I am using ESP-IDF version 4.4.4 because it is stable version and I would suggest to write basic code on this version. If you want to download this version just go to ESP_IDF link or run the following block command after obviously you’ve selected your desired dir. I am using Ubuntu 20.0.5 because its faster compared to windows while compiling my code. Let’s start!

git clone -b v4.4 - recursive https://github.com/espressif/esp-idf.git esp-idf-v4.4

Step 1# Open VS Code/view and select command palette or cntrl+shift+p

A new project window will pop up, select your board directory esp32 board and serial port will be selected by default .If it shows no port then close the window plug in your ESP32 and open window again.

Project Window

Step #2 Now click on Choose Template and a window will pop up showing examples template of different code type you want to choose from , nope we will not select WiFi example but we will choose sample project and start coding.

Choose Sample Project

Step #3 Let’s code

I can write the code for you here or maybe give you a GitHub link to my repo but that would not be a great practice, so instead I would write code here step by step and show you final output and what each function is doing and why is this necessary.

First I will code necessary libs includes so one know why are they important only one line explanation in comments would be enough.

#include <stdio.h> //for basic printf commands
#include <string.h> //for handling strings
#include "freertos/FreeRTOS.h" //for delay,mutexs,semphrs rtos operations
#include "esp_system.h" //esp_init funtions esp_err_t
#include "esp_wifi.h" //esp_wifi_init functions and wifi operations
#include "esp_log.h" //for showing logs
#include "esp_event.h" //for wifi event
#include "nvs_flash.h" //non volatile storage
#include "lwip/err.h" //light weight ip packets error handling
#include "lwip/sys.h" //system applications for light weight ip apps
const char *ssid = "your ssid"
const char *pass = "your password"

After header files we need to create an event handler function. What is an event function and why is it important? While dealing with FreeRTOS applications it is important to establish a function which handles every instance of a specific task which is taking place. Event handler is a function which is executed whenever an event is triggered in this case it is WiFi event. WiFi itself is composed of various situations like getting SSID and PASSWORD, scanning the environment for the given SSID and PASSWORD, after scanning connecting, connected successful or connected unsuccessful or disconnected after connected etc.

All these event are to be monitored in a switch case of if-else statement while the program is running. So lets write the event handler function. I am using if else to keep it simple , you can use switch case as well.Also I am using printf only and not logs for keeping is simple.

static void wifi_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,void *event_data){
if(event_id == WIFI_EVENT_STA_START)
{
printf("WIFI CONNECTING....\n");
}
else if (event_id == WIFI_EVENT_STA_CONNECTED)
{
printf("WiFi CONNECTED\n");
}
else if (event_id == WIFI_EVENT_STA_DISCONNECTED)
{
printf("WiFi lost connection\n");
if(retry_num<5){esp_wifi_connect();retry_num++;printf("Retrying to Connect...\n");}
}
else if (event_id == IP_EVENT_STA_GOT_IP)
{
printf("Wifi got IP...\n\n");
}
}

As you can see in each if else statement event_id is a variable which decides which statement to execute, depending on this id which is assigned a value based on the events occurring in back end the specific printf statement is triggered. Also we can run functions in specific event if the programs requires.

Note: In event disconnected I am calling esp_wifi_connect(); function which is a predefined function in esp_wifi.h to reconnected to wifi for 5 times if it ever gets disconnected.

Now lets code more, we need another function in which event handler function gets managed lets called it wifi_connection() this will be called in void app_main(). Funtion wifi_connection will contain initialize functions and event handler register of event handler we just created. I have briefly explained in comments what each function does (for details Google or GPT it :D).

void wifi_connection(){
esp_netif_init(); //network interdace initialization
esp_event_loop_create_default(); //responsible for handling and dispatching events
esp_netif_create_default_wifi_sta(); //sets up necessary data structs for wifi station interface
wifi_init_config_t wifi_initiation = WIFI_INIT_CONFIG_DEFAULT();//sets up wifi wifi_init_config struct with default values
esp_wifi_init(&wifi_initiation); //wifi initialised with dafault wifi_initiation
esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);//creating event handler register for wifi
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL);//creating event handler register for ip event
wifi_config_t wifi_configuration ={ //struct wifi_config_t var wifi_configuration
.sta= {
.ssid = "";
.password= ""; /*we are sending a const char of ssid and password which we will strcpy in following line so leaving it blank*/
}//also this part is used if you donot want to use Kconfig.projbuild
};
strcpy((char*)wifi_configuration.sta.ssid,your_ssid); // copy chars from hardcoded configs to struct
strcpy((char*)wifi_configuration.sta.password,your_pass);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_configuration);//setting up configs when event ESP_IF_WIFI_STA
esp_wifi_start();c//start connection with configurations provided in funtion
esp_wifi_set_mode(WIFI_MODE_STA);//station mode selected
esp_wifi_connect(); //connect with saved ssid and pass
printf( "wifi_init_softap finished. SSID:%s password:%s",ssid,pass);
}

The funtion esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL); is a function which controls and triggers wifi_event_handler we just created before and sends in event_id based on which entire event handler code runs.

Let’s call it in void app_main()

void app_main(void){
nvs_flash_init(); // this is important in wifi case to store configurations , code will not work if this is not added
wifi_connection();
}

Output

Successful connection of WiFi

I hope this raw wifi code was helpful fro esp-idf beginners and they will learn how to not rely on examples because it would be hard to integrate more features if you only follow examples provided. Always write your own code and blame on pc if it does not work :D

For more details do not text me on LinkedIn but add me on Discord shahrukh517#4777. Cheers!

Bonus: Entire code just copy paste and enjoy!

#include <stdio.h> //for basic printf commands
#include <string.h> //for handling strings
#include "freertos/FreeRTOS.h" //for delay,mutexs,semphrs rtos operations
#include "esp_system.h" //esp_init funtions esp_err_t
#include "esp_wifi.h" //esp_wifi_init functions and wifi operations
#include "esp_log.h" //for showing logs
#include "esp_event.h" //for wifi event
#include "nvs_flash.h" //non volatile storage
#include "lwip/err.h" //light weight ip packets error handling
#include "lwip/sys.h" //system applications for light weight ip apps

const char *ssid = "";
const char *pass = "";
int retry_num=0;
static void wifi_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,void *event_data){
if(event_id == WIFI_EVENT_STA_START)
{
printf("WIFI CONNECTING....\n");
}
else if (event_id == WIFI_EVENT_STA_CONNECTED)
{
printf("WiFi CONNECTED\n");
}
else if (event_id == WIFI_EVENT_STA_DISCONNECTED)
{
printf("WiFi lost connection\n");
if(retry_num<5){esp_wifi_connect();retry_num++;printf("Retrying to Connect...\n");}
}
else if (event_id == IP_EVENT_STA_GOT_IP)
{
printf("Wifi got IP...\n\n");
}
}

void wifi_connection()
{
// s1.4
// 2 - Wi-Fi Configuration Phase
esp_netif_init();
esp_event_loop_create_default(); // event loop s1.2
esp_netif_create_default_wifi_sta(); // WiFi station s1.3
wifi_init_config_t wifi_initiation = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_initiation); //
esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL);
wifi_config_t wifi_configuration = {
.sta = {
.ssid = "",
.password = "",

}

};
strcpy((char*)wifi_configuration.sta.ssid, ssid);
strcpy((char*)wifi_configuration.sta.password, pass);
//esp_log_write(ESP_LOG_INFO, "Kconfig", "SSID=%s, PASS=%s", ssid, pass);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_configuration);
// 3 - Wi-Fi Start Phase
esp_wifi_start();
esp_wifi_set_mode(WIFI_MODE_STA);
// 4- Wi-Fi Connect Phase
esp_wifi_connect();
printf( "wifi_init_softap finished. SSID:%s password:%s",ssid,pass);

}

void app_main(void)
{
nvs_flash_init();
wifi_connection();

}

--

--

Fateh Ali Shahrukh Khan

I am an Embedded Firmware Engineer, passionate about IOT and microcontrollers. Add me on Discord if you have any questions shahrukh517#4777