ESP32 development notes (three) source code example 21_WIFI_STA_TCP_Client realizes TCP client in station mode STA

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

Introduction to Station Mode

Station mode is also called station work mode, similar to wireless terminal

The ESP32 in Station mode can be connected to AP (WIFI router). Through Station (referred to as "STA") mode, ESP32 connects to the routed wifi signal as a client.

Basic wireless network based on AP (Infra): Infra: Also known as basic network, it is created by AP, and many STAs join the wireless network. The characteristic of this type of network is that AP is the center of the entire network. All communications are forwarded and completed through the AP. 

In this mode, the device can directly access the external network and internal network through the IP address assigned by the AP. The schematic diagram is as follows:

TCP introduction

Transmission Control Protocol (TCP, Transmission Control Protocol) is a connection-oriented, reliable, byte stream-based transport layer communication protocol.

TCP is designed to adapt to the layered protocol hierarchy that supports multiple network applications. The paired processes in host computers connected to different but interconnected computer communication networks rely on TCP to provide reliable communication services. TCP assumes that it can obtain simple, possibly unreliable datagram services from lower-level protocols. In principle, TCP should be able to operate on various communication systems ranging from hard-wired connections to packet-switched or circuit-switched networks.

TCP is divided into a server server and a client client. The server creates a service and waits for the client to connect. After the client connects, it can send messages to the server. There is only one server, and there can be N clients, which can connect to the server at the same time. , The server cannot actively connect to the client, the client must actively connect to the server to send messages to each other.

experiment process

1. ESP32 create station mode to connect to WIFI

3. Create a TCP Server on the computer (the computer must be under the same router as the development board)

2. After the connection is successful, ESP32 creates a TCP Client and starts to connect to the computer

4. Send data to each other

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"
#include "driver/gpio.h"

Write the main function


// 主函数
void app_main(void)
{
	ESP_LOGI(TAG, "APP Start......");
	// 配置GPIO结构体
	gpio_config_t io_conf;
	io_conf.intr_type = GPIO_INTR_ANYEDGE;		// 下降沿和上升沿触发中断
	io_conf.pin_bit_mask = 1 << 0;	// 设置GPIO号
	io_conf.mode = GPIO_MODE_INPUT;				// 模式输入
	io_conf.pull_up_en = GPIO_PULLUP_ENABLE;	// 端口上拉使能
	gpio_config(&io_conf);

	//初始化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_sta();// WIFI作为STA的初始化
	while(1){
		vTaskDelay(100 / portTICK_RATE_MS);
		if(gpio_get_level(0)==0){
			//新建一个tcp连接任务
			xTaskCreate(&tcp_connect, "tcp_connect", 4096, NULL, 5, NULL);
			break;
		}
	}
	gpio_pad_select_gpio(LED_GPIO);// 选择要操作的GPIO
	gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);// 设置GPIO为推挽输出模式

	while(1) {
		gpio_set_level(LED_GPIO, 0);// GPIO输出低
		vTaskDelay(500 / portTICK_PERIOD_MS);
		gpio_set_level(LED_GPIO, 1);// GPIO输出高
		vTaskDelay(500 / portTICK_PERIOD_MS);
	}
}

Modify the WIFI name and password, modify it to the WIFI at home, modify TCP_SERVER_ADRESS to the IP address of the computer

#define WIFI_SSID				"TP-YIXIN"			// WIFI 网络名称
#define WIFI_PAS				"a12345678"			// WIFI 密码
#define TCP_SERVER_ADRESS		"192.168.0.252"		// 作为client,要连接TCP服务器地址

Create STA station mode and connect to WIFI

// WIFI作为STA的初始化
void wifi_init_sta()
{
	tcp_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 = {
		.sta = {
			.ssid = WIFI_SSID,
			.password = WIFI_PAS},
	};
	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());
	ESP_LOGI(TAG, "wifi_init_sta finished.");
	ESP_LOGI(TAG, "connect to ap SSID:%s password:%s \n",WIFI_SSID, WIFI_PAS);
}

Create a TCP connection task

// 任务:建立TCP连接并从TCP接收数据
static void tcp_connect(void *pvParameters)
{
	while (1){
		g_rxtx_need_restart = false;
		//等待WIFI连接信号量,死等
		xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
		ESP_LOGI(TAG, "start tcp connected");
		TaskHandle_t tx_rx_task = NULL;
		//延时3S准备建立clien
		vTaskDelay(3000 / portTICK_RATE_MS);
		ESP_LOGI(TAG, "create tcp Client");
		//建立client
		int socket_ret = create_tcp_client();
		if (socket_ret == ESP_FAIL){
			ESP_LOGI(TAG, "create tcp socket error,stop...");
			continue;
		}else{
			ESP_LOGI(TAG, "create tcp socket succeed...");            
			//建立tcp接收数据任务
			if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)){
				ESP_LOGI(TAG, "Recv task create fail!");
			}else{
				ESP_LOGI(TAG, "Recv task create succeed!");
			}
		}
		while (1){
			vTaskDelay(3000 / portTICK_RATE_MS);
			//重新建立client,流程和上面一样
			if (g_rxtx_need_restart){
				vTaskDelay(3000 / portTICK_RATE_MS);
				ESP_LOGI(TAG, "reStart create tcp client...");
				//建立client
				int socket_ret = create_tcp_client();
				if (socket_ret == ESP_FAIL){
					ESP_LOGE(TAG, "reStart create tcp socket error,stop...");
					continue;
				}else{
					ESP_LOGI(TAG, "reStart create tcp socket succeed...");
					//重新建立完成,清除标记
					g_rxtx_need_restart = false;
					//建立tcp接收数据任务
					if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)){
						ESP_LOGE(TAG, "reStart Recv task create fail!");
					}else{
						ESP_LOGI(TAG, "reStart Recv task create succeed!");
					}
				}
			}
		}
	}
	vTaskDelete(NULL);
}

Create TCP client

// 建立tcp client
esp_err_t create_tcp_client()
{
	ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d",TCP_SERVER_ADRESS, TCP_PORT);
	//新建socket
	connect_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (connect_socket < 0){
		show_socket_error_reason("create client", connect_socket);//打印报错信息
		close(connect_socket);//新建失败后,关闭新建的socket,等待下次新建
		return ESP_FAIL;
	}
	//配置连接服务器信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(TCP_PORT);
	server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_ADRESS);
	ESP_LOGI(TAG, "connectting server...");
	//连接服务器
	if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
		show_socket_error_reason("client connect", connect_socket);//打印报错信息
		ESP_LOGE(TAG, "connect failed!");
		//连接失败后,关闭之前新建的socket,等待下次新建
		close(connect_socket);
		return ESP_FAIL;
	}
	ESP_LOGI(TAG, "connect success!");
	return ESP_OK;
}

Write data receiving and processing tasks

// 接收数据任务
void recv_data(void *pvParameters)
{
	int len = 0;            //长度
	char databuff[1024];    //缓存
	while (1){
		//清空缓存
		memset(databuff, 0x00, sizeof(databuff));
		//读取接收数据
		len = recv(connect_socket, databuff, sizeof(databuff), 0);
		g_rxtx_need_restart = false;
		if (len > 0){
			ESP_LOGI(TAG, "recvData: %s", databuff);//打印接收到的数组
			//接收数据回发
			send(connect_socket, databuff, strlen(databuff), 0);
			//sendto(connect_socket, databuff , sizeof(databuff), 0, (struct sockaddr *) &remote_addr,sizeof(remote_addr));
		}else{
			show_socket_error_reason("recv_data", connect_socket);//打印错误信息
			g_rxtx_need_restart = true;//服务器故障,标记重连
			break;
		}
	}
	close_socket();
	g_rxtx_need_restart = true;//标记重连
	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_STA_START:        //STA模式-开始连接
		esp_wifi_connect();
		break;
	case SYSTEM_EVENT_STA_DISCONNECTED: //STA模式-断线
		esp_wifi_connect();
		xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT);
		break;
	case SYSTEM_EVENT_STA_CONNECTED:    //STA模式-连接成功
		xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
		break;
	case SYSTEM_EVENT_STA_GOT_IP:       //STA模式-获取IP
		ESP_LOGI(TAG, "got ip:%s\n",ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));xEventGroupSetBits(tcp_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\21_WIFI_STA_TCP_Client

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

When the development board is successfully connected to WIFI, it will print WIFI_STA_TCP_Client Demo: got ip:192.168.XXX.XXX

Open the computer network assistant

Network Assistant chooses TCP Server 

Local host address: drop down to select the IP address of this computer

Local host port: 9527

Click open

Press the BOOT button on the development board to start creating TCP Client

When the computer sends data, the development board will return the data as it is

Guess you like

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