ESP32 Development Notes (3) Source code example 18_WIFI_AP_UDP Realize UDP communication in soft AP mode

Development board purchase link

https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674

Introduction to development board
development environment to build windows
basic routines:
    0_Hello Bug (ESP_LOGX and printf)     project template/print debugging output
    1_LED                                                     LED on and off control       
    2_LED_Task                                           control LED using task mode
    3_LEDC_PWM                                       use LEDC to control LED to achieve breathing light effect
    4_ADC_LightR                                       use ADC to read Photoresistor to achieve light sensing
    5_KEY_Short_Long                               button long press and short press to achieve
    6_TouchPad_Interrupt                           capacitive touch interrupt to achieve
    7_WS2812_RMT                                   using RMT to achieve RGB_LED rainbow color example
    8_DHT11_RMT to                                     use RMT to read DHT11 temperature and humidity sensor
    9_SPI_SDCard                                     uses SPI bus to implement TF card file system example
    10_IIC_ADXL345                                 uses IIC bus to implement reading ADXL345 angular acceleration sensor
    11_IIC_AT24C02                                  uses IIC bus to implement small-capacity data storage test
    12_IR_Rev_RMT                                 uses RMT to implement infrared remote control receiving and decoding (NEC encoding)
    13_IR_Send_RMT                               uses RMT to implement infrared data transmission (NEC code)
    14_WIFI_Scan                                     nearby WIFI signal scanning example    
    15_WIFI_AP                                         creating a soft AP example
    16_WIFI_AP_TCP_Server                   realizes TCP server                    in soft AP mode
    17_WIFI_AP_TCP_Client realizes TCP client in soft AP mode
    18_WIFI_AP_UDP                              Achieved at the soft AP mode UDP communication
    19_WIFI_STA                                       create STA slave mode connected to the router
    20_WIFI_STA_TCP_Server                 implement TCP server in slave mode STA
    21_WIFI_STA_TCP_Client                 implemented in slave mode STA TCP client
    22_WIFI_STA_UDP                             implemented UDP communications slave mode STA
    23_LCD_Test the LCD LCD touch screen display test 
    24_LVGL_Test LVGL graphics library simple example

AP mode introduction

An access point (AP) is a device that provides Wi-Fi network access and connects it to a wired network. In addition to not having an interface with a wired network, ESP32 can also provide similar functions. This mode of operation is called soft-access point (soft-AP). The maximum number of stations that can connect to the soft-AP at the same time can be set to 4, and the default is 4.

When ESP32 is in AP mode alone, it can be regarded as a LAN WiFi router node that cannot access the external network. It can accept connection requests from various devices. And it can be connected with the connecting device through TCP and UDP to realize data flow. It can take on the role of data receiving and sending nodes in the design of local Internet of Things.

Introduction to UDP protocol

UDP (User Datagram Protocol, User Datagram Protocol)
UDP is a transport layer protocol. Its function is to add the most basic services to the IP datagram service: multiplexing and demultiplexing and error detection.

UDP provides unreliable services and has advantages that TCP does not:

UDP has no connection, and there is no time delay required to establish a connection. Spatially, TCP needs to maintain the connection state in the end system, which requires a certain amount of overhead. This connection loads parameters including receiving and sending buffers, congestion control parameters, and sequence numbers and confirmation numbers. UCP does not maintain the connection state, nor does it track these parameters, so the overhead is small. Both space and time have advantages.
for example:

If DNS runs on TCP instead of UDP, the speed of DNS will be much slower.
HTTP uses TCP instead of UDP because reliability is very important for web pages based on text data.
When the same kind of dedicated application server supports UDP, it must be able to support more active clients.

The packet header overhead is small**, the TCP header is 20 bytes, and the UDP header is 8 bytes.

UDP has no congestion control. The application layer can better control the data to be sent and the sending time. Congestion control in the network will not affect the sending rate of the host. Certain real-time applications require transmission at a stable speed, which can tolerate some data loss, but cannot allow a large delay (such as real-time video, live broadcast, etc.)

UDP provides best-effort delivery and does not guarantee reliable delivery. All work to maintain transmission reliability requires users to complete at the application layer. There is no TCP confirmation mechanism or retransmission mechanism. If it is not transmitted to the opposite end due to network reasons, UDP will not return an error message to the application layer.

UDP is message-oriented. For the messages handed down by the application layer, the header is added and delivered directly to the IP layer. It neither merges nor splits, and retains the boundaries of these messages. The UDP user datagram delivered to the IP layer is delivered to the upper application process intact after the header is removed. The message is indivisible and is the smallest unit of UDP datagram processing.
Because of this, UDP is not flexible enough to control the frequency and amount of data read and write. For example, if we want to send a message of 100 bytes, we call the sendto function once to send 100 bytes, and the opposite end also needs to use the recvfrom function to receive 100 bytes at a time. You cannot use the loop to get 10 bytes each time. Do this ten times.

UDP is commonly used in network applications that transmit relatively small amounts of data at one time, such as DNS, SNMP, etc., because for these applications, if TCP is used, it will bring a lot of overhead for connection creation, maintenance and teardown. UDP is also often used in multimedia applications (such as IP telephony, real-time video conferencing, streaming media, etc.). The reliable transmission of data is not important to them. The congestion control of TCP will cause them to have a large delay, which is also intolerable.

experiment process

1. Create AP with ESP32

2. Create a UDP listener

3. Wait for the computer/mobile phone to connect to the AP created by this ESP32

4. Wait for the UDP in the computer/mobile phone to send a message, and return the message as it is

One, write code

First quote the necessary header files

#include <stdio.h>
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include <string.h>
#include <sys/socket.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"

Write the main function

// 主函数
void app_main(void)
{
	ESP_LOGI(TAG, "APP Start......");
	//初始化flash
	esp_err_t ret = nvs_flash_init();
	if (ret == ESP_ERR_NVS_NO_FREE_PAGES){
		ESP_ERROR_CHECK(nvs_flash_erase());
		ret = nvs_flash_init();
	}
	ESP_ERROR_CHECK(ret);
	wifi_init_softap();
	//新建一个udp连接任务
    xTaskCreate(&udp_connect, "udp_connect", 4096, NULL, 5, NULL);
}

Create AP function

// WIFI作为AP的初始化
void wifi_init_softap()
{
	udp_event_group = xEventGroupCreate();
	tcpip_adapter_init();
	ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	ESP_ERROR_CHECK(esp_wifi_init(&cfg));
	wifi_config_t wifi_config = {
		.ap = {
			.ssid = SOFT_AP_SSID,
			.password = SOFT_AP_PAS,
			.ssid_len = 0,
			.max_connection = SOFT_AP_MAX_CONNECT,
			.authmode = WIFI_AUTH_WPA_WPA2_PSK,
		},
	};
	if (strlen(SOFT_AP_PAS) == 0){
		wifi_config.ap.authmode = WIFI_AUTH_OPEN;
	}
	ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP) );
	ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
	ESP_ERROR_CHECK(esp_wifi_start());
	ESP_LOGI(TAG, "SoftAP set finish,SSID:%s password:%s \n",wifi_config.ap.ssid, wifi_config.ap.password);
}

UDP connection task

// 建立UDP连接并从UDP接收数据
static void udp_connect(void *pvParameters)
{
	//等待WIFI连接成功事件,死等
	xEventGroupWaitBits(udp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
	ESP_LOGI(TAG, "start udp connected");
	vTaskDelay(3000 / portTICK_RATE_MS);
	ESP_LOGI(TAG, "create udp Client");
	int socket_ret = create_udp_client();
	if (socket_ret == ESP_FAIL){
		ESP_LOGI(TAG, "create udp socket error,stop...");
		vTaskDelete(NULL);
	}else{
		ESP_LOGI(TAG, "create udp socket succeed...");            
		//建立UDP接收数据任务
		if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, NULL)){
			ESP_LOGI(TAG, "Recv task create fail!");
			vTaskDelete(NULL);
		}else{
			ESP_LOGI(TAG, "Recv task create succeed!");
		}
	}
	vTaskDelete(NULL);
}

Create UDP function

// 建立udp client
esp_err_t create_udp_client()
{
	ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d",UDP_ADRESS, UDP_PORT);
	//新建socket
	connect_socket = socket(AF_INET, SOCK_DGRAM, 0);                         /*参数和TCP不同*/
	if (connect_socket < 0){
		//打印报错信息
		show_socket_error_reason("create client", connect_socket);
		//新建失败后,关闭新建的socket,等待下次新建
		close(connect_socket);
		return ESP_FAIL;
	}
	//配置连接服务器信息
	client_addr.sin_family = AF_INET;
	client_addr.sin_port = htons(UDP_PORT);
	client_addr.sin_addr.s_addr = inet_addr(UDP_ADRESS);

	struct sockaddr_in Loacl_addr; 
	Loacl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	Loacl_addr.sin_family = AF_INET;
	Loacl_addr.sin_port = htons(UDP_PORT); //设置本地端口
	uint8_t res = 0;
	res = bind(connect_socket,(struct sockaddr *)&Loacl_addr,sizeof(Loacl_addr));
	if(res != 0){
		printf("bind error\n");

	}



	int len = 0;            //长度
	char databuff[1024] = "Hello Server,Please ack!!";    //缓存
	//测试udp server
	len = sendto(connect_socket, databuff, 1024, 0, (struct sockaddr *) &client_addr,sizeof(client_addr));
	if (len > 0) {
		ESP_LOGI(TAG, "Transfer data to %s:%u,ssucceed\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
	} else {
		show_socket_error_reason("recv_data", connect_socket);
		close(connect_socket);
		return ESP_FAIL;
	}
	return ESP_OK;
}

Receiving and processing data tasks

// 接收数据任务
void recv_data(void *pvParameters)
{
	int len = 0;            //长度
	char databuff[1024];    //缓存
	while (1){
		memset(databuff, 0x00, sizeof(databuff));//清空缓存
		//读取接收数据
		len = recvfrom(connect_socket, databuff, sizeof(databuff), 0,(struct sockaddr *) &client_addr, &socklen);
		if (len > 0){
			//打印接收到的数组
			ESP_LOGI(TAG, "UDP Client recvData: %s", databuff);
			//接收数据回发
			sendto(connect_socket, databuff, strlen(databuff), 0,(struct sockaddr *) &client_addr, sizeof(client_addr));
		}else{
			//打印错误信息
			show_socket_error_reason("UDP Client recv_data", connect_socket);
			break;
		}
	}
	close_socket();
	vTaskDelete(NULL);
}

WIFI event handling

// wifi 事件
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch (event->event_id)
    {
	case SYSTEM_EVENT_AP_STACONNECTED:  //AP模式-有STA连接成功
		//作为ap,有sta连接
		ESP_LOGI(TAG, "station:" MACSTR " join,AID=%d\n",MAC2STR(event->event_info.sta_connected.mac),event->event_info.sta_connected.aid);
		xEventGroupSetBits(udp_event_group, WIFI_CONNECTED_BIT);
		break;
	case SYSTEM_EVENT_AP_STADISCONNECTED://AP模式-有STA断线
		ESP_LOGI(TAG, "station:" MACSTR "leave,AID=%d\n",MAC2STR(event->event_info.sta_disconnected.mac),event->event_info.sta_disconnected.aid);
		xEventGroupClearBits(udp_event_group, WIFI_CONNECTED_BIT);
		break;
	default:
		break;
    }
    return ESP_OK;
}

Two, download test

Open ESP-IDF Command Prompt

cd command to enter this project directory

cd F:\ESP32_DevBoard_File\18_WIFI_AP_UDP

View the serial port number of the development board in the computer device manager

Execute idf.py -p COM9 flash monitor to download and run from serial port 9 and open the port to display device debugging information Ctrl+c to exit

Test process

After downloading the code, the computer waits for the "HelloBug" WIFI to appear, connect to it, and the password is 12345678 (can be changed in the code)

After the connection is successful, open the network debugging assistant on the computer side

Select the connection method as "UDP" 

Local host address: 192.168.4.2 (can be found in the print information of the development board/in the local connection status of the computer)

Local host port: 1257 (can not be 9527 casually, the port of the development board is 9527)

Click connect

Remote host input 192.168.4.1: 9527 or 255.255.255.255: 9527

Send data, the development board will return the same data, check the serial port information for details.

The test results are as follows:

Guess you like

Origin blog.csdn.net/cnicfhnui/article/details/108590638