Index
In the ESP-IDF framework, networking is a critical feature, allowing the ESP32 to connect to Wi-Fi networks and use TCP/IP protocols for data transmission over a network. ESP-IDF provides libraries to handle Wi-Fi and TCP/IP connectivity, making it easier to build IoT applications within FreeRTOS.
Here’s an example of setting up the ESP32 as a Wi-Fi client (station mode) and establishing a TCP connection to a remote server. We’ll use FreeRTOS tasks to handle Wi-Fi connectivity and data transmission.
Example: Wi-Fi Client and TCP Connection
This example demonstrates:
- Setting up Wi-Fi to connect to a specific SSID.
- Creating a TCP client that connects to a server and sends a message.
Setup
- Replace
"your_ssid"
and"your_password"
with your Wi-Fi network credentials. - Specify the server IP and port (replace
"192.168.1.10"
and8080
with your server’s IP address and port number).
Code Example
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#define WIFI_SSID "your_ssid"
#define WIFI_PASS "your_password"
#define SERVER_IP "192.168.1.10" // Replace with the server IP
#define SERVER_PORT 8080 // Replace with the server port
static const char *TAG = "WiFi_TCP_Client";
void wifi_init_sta(void);
void tcp_client_task(void *pvParameters);
// Event handler for Wi-Fi events
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
ESP_LOGI(TAG, "Disconnected from Wi-Fi, reconnecting...");
esp_wifi_connect();
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "Got IP: %s", ip4addr_ntoa(&event->ip_info.ip));
xTaskCreate(tcp_client_task, "tcp_client_task", 4096, NULL, 5, NULL);
}
}
void wifi_init_sta() {
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, &instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
void tcp_client_task(void *pvParameters) {
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(SERVER_PORT);
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
vTaskDelete(NULL);
return;
}
ESP_LOGI(TAG, "Socket created, connecting to %s:%d", SERVER_IP, SERVER_PORT);
int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err != 0) {
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
close(sock);
vTaskDelete(NULL);
return;
}
ESP_LOGI(TAG, "Successfully connected");
while (1) {
char payload[] = "Hello, Server!";
int err = send(sock, payload, strlen(payload), 0);
if (err < 0) {
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Message sent");
// Delay for a few seconds before sending the next message
vTaskDelay(pdMS_TO_TICKS(5000));
}
if (sock != -1) {
ESP_LOGE(TAG, "Shutting down socket and restarting...");
shutdown(sock, 0);
close(sock);
}
vTaskDelete(NULL);
}
void app_main() {
// Initialize NVS for Wi-Fi storage
esp_err_t ret = nvs_flash_init();
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);
// Initialize Wi-Fi and connect
wifi_init_sta();
}
Explanation
- Wi-Fi Initialization:
- We start by initializing NVS, required for Wi-Fi credentials storage.
- The
wifi_init_sta()
function sets up Wi-Fi in station mode, configures the SSID and password, and starts Wi-Fi.
- Wi-Fi Event Handler:
- The
wifi_event_handler
function manages Wi-Fi events. - When the device connects to Wi-Fi (
WIFI_EVENT_STA_START
), it attempts to reconnect if disconnected (WIFI_EVENT_STA_DISCONNECTED
). - Once an IP address is obtained (
IP_EVENT_STA_GOT_IP
), thetcp_client_task
is created to start the TCP connection.
- The
- TCP Client Task:
- Socket Creation: We create a socket and attempt to connect to the specified server IP and port.
- Sending Data: The task sends a “Hello, Server!” message every 5 seconds.
- If any error occurs, it shuts down the socket and stops the task.
- Logging:
ESP_LOGI
andESP_LOGE
are used to log informational and error messages, providing visibility into Wi-Fi and TCP operations.
Key Concepts
- FreeRTOS and ESP-IDF Integration: ESP-IDF manages networking, allowing tasks to handle Wi-Fi and socket communication asynchronously.
- TCP/IP Protocol: The example uses a TCP connection, suitable for reliable data exchange.
- Event Handling: The
wifi_event_handler
manages Wi-Fi events, ensuring the TCP client task is started only once the ESP32 is connected to Wi-Fi and has an IP address. - Task Management: FreeRTOS tasks are created to handle Wi-Fi and TCP connections separately, allowing for asynchronous, non-blocking networking.
Example Output
The output will look similar to this:
I (1000) WiFi_TCP_Client: Connecting to Wi-Fi...
I (1500) WiFi_TCP_Client: Got IP: 192.168.1.100
I (1500) WiFi_TCP_Client: Socket created, connecting to 192.168.1.10:8080
I (1600) WiFi_TCP_Client: Successfully connected
I (1600) WiFi_TCP_Client: Message sent
I (6600) WiFi_TCP_Client: Message sent
This example shows how to use ESP-IDF’s Wi-Fi and TCP/IP libraries within FreeRTOS to create a reliable network connection and exchange data.