【建筑施工监测与安防系统】七、Kaluga测试TCP Client
[复制链接]
Kaluga板既然以ESP32S2为主控,自然要将Wi-Fi用起来。
1、tcp client案例
IDF附带的案例中包含tcp client案例,即“..\esp-idf-v4.4\examples\protocols\sockets\tcp_client”。于是,本人先拷贝tcp_client目录,并进行初步测试——功能就是向Server发送一句,如果Server回传信息,则ESP32会继续发送。
整个案例的main.c代码比较简单,一度找不到连接Wi-Fi的语句,直到看到app_main()中的代码。
图7-1 tcp client案例的入口函数
再看案例的CMakeLists.txt中有一句:set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
于是,查看这个案例的代码,终于在protocol_examples_common的connect.c中看到了wifi_start()函数,其中包含连接Wi-Fi的代码。可气的是,经过半天的代码追踪,最后在IDF案例中看到了“wifi/getting_started/station”,里面有完整的连接AP代码,真是绕了一个弯子。
2、连接Wi-Fi AP
不过,无论是哪个案例,SSID和密码字串都是通过menuconfig来配置的,也就是需要编写项目main目录下的Kconfig.probuild文件。每次修改menuconfig都等于要rebuild项目,感觉太麻烦了,所以决定直接定义宏来设置SSID和密码。
连接Wi-Fi需要连接的头文件——当然这里在下采用“无脑抄”,直接将station案例中的头文件连接代码给拷贝过来了。
- #include <string.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/event_groups.h"
- #include "esp_system.h"
- #include "esp_wifi.h"
- #include "esp_event.h"
- #include "esp_log.h"
-
- #include "lwip/err.h"
- #include "lwip/sys.h"
接着就是定义宏和事件回调函数,AITA_WIFI_SSID和AITA_WIFI_PSW分别是SSID名称和密码,AITA_WIFI_MAX_RETRY是尝试连接AP的最大次数,这里设置5次。整个连接过程需要了解Wi-Fi状态,可以通过获取系统事件来判断。event_handler()就是定义的事件回调函数,捕获WIFI_EVENT_STA_START、WIFI_EVENT_STA_DISCONNECTED、IP_EVENT_STA_GOT_IP这三个系统事件。并且定义标志组aita_wifi_event_group,不同的系统事件置位标志组的不同bit,以此来记录事件的发生并给予对应的处理——仅是串口输出不同的提示信息。
- #define AITA_WIFI_SSID "yourssid" //WIFI AP SSID
- #define AITA_WIFI_PSW "yourpsw" //WIFI AP Password
- #define AITA_WIFI_MAX_RETRY 5 //retry times of connecting
- #define AITA_WIFI_CONN_BIT BIT0 //connected flag
- #define AITA_WIFI_FAIL_BIT BIT1 //connecting fail flag
-
- #define TAG "AITA WIFI" //LOG tag
-
- EventGroupHandle_t aita_wifi_event_group;
- int aita_retry_num = 0;
-
-
- void 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) {
-
- if(aita_retry_num < AITA_WIFI_MAX_RETRY) {
- esp_wifi_connect();
- aita_retry_num++;
- ESP_LOGI(TAG, "retry to connect to the AP");
- } else {
-
- xEventGroupSetBits(aita_wifi_event_group, AITA_WIFI_FAIL_BIT);
- }
- ESP_LOGI(TAG,"connect to the AP fail");
- } 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:" IPSTR, IP2STR(&event->ip_info.ip));
- aita_retry_num = 0;
- xEventGroupSetBits(aita_wifi_event_group, AITA_WIFI_CONN_BIT);
- }
- }
-
- void wifi_init_sta(void) {
-
- aita_wifi_event_group = xEventGroupCreate();
-
- 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,
- &event_handler,
- NULL,
- &instance_any_id));
- ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
- IP_EVENT_STA_GOT_IP,
- &event_handler,
- NULL,
- &instance_got_ip));
-
- wifi_config_t wifi_config = {
- .sta = {
- .ssid = AITA_WIFI_SSID,
- .password = AITA_WIFI_PSW,
- .threshold.authmode = WIFI_AUTH_WPA2_PSK,
- .pmf_cfg = {
- .capable = true,
- .required = false
- },
- },
- };
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
- ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
- ESP_ERROR_CHECK(esp_wifi_start());
- ESP_LOGI(TAG, "wifi_init_sta finished.");
-
- EventBits_t bits = xEventGroupWaitBits(aita_wifi_event_group,
- AITA_WIFI_CONN_BIT | AITA_WIFI_FAIL_BIT,
- pdFALSE,
- pdFALSE,
- portMAX_DELAY);
-
- if(bits & AITA_WIFI_CONN_BIT) {
- ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
- AITA_WIFI_SSID, AITA_WIFI_PSW);
- } else if(bits & AITA_WIFI_FAIL_BIT) {
- ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
- AITA_WIFI_SSID, AITA_WIFI_PSW);
- } else {
- ESP_LOGE(TAG, "UNEXPECTED EVENT");
- }
-
-
- ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
- ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
- vEventGroupDelete(aita_wifi_event_group);
- }
3、tcp连接
本篇的测试案例是在上篇的“Kaluga的adc_button案例结合lvgl”基础之上扩展,再创建一个TCP Client连接任务,任务函数tcp_client_task()功能是向TCP Server发送固定信息,Server可以回传“RED、GREEN、BLUE、YELLOW、PURPLE、WHITE”这六个命令。Client收到命令后发出消息到队列——这样点灯任务led_task就会点亮不同的颜色。
因为是在上一例子基础扩展,而上例是按键控灯,按键会发送不同的电压值作为消息,tcp_client_task()干脆也发送电压值作为消息。
- #define HOST_IP_ADDR "192.168.31.74"
- #define PORT 1234
- const char *payload = "Message from ESP32 ";
-
- static void tcp_client_task(void *arg) {
- char rx_buffer[128];
- char host_ip[] = HOST_IP_ADDR;
- int addr_family = 0;
- int ip_protocol = 0;
-
- while (1) {
- struct sockaddr_in dest_addr;
- dest_addr.sin_addr.s_addr = inet_addr(host_ip);
- dest_addr.sin_family = AF_INET;
- dest_addr.sin_port = htons(PORT);
- addr_family = AF_INET;
- ip_protocol = IPPROTO_IP;
-
- int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
- if(sock < 0) {
- ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
- break;
- }
- ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT);
-
- int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));
- if(err != 0) {
- ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
- break;
- }
- ESP_LOGI(TAG, "Successfully connected");
-
- while(1) {
- int err = send(sock, payload, strlen(payload), 0);
- if (err < 0) {
- ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
- break;
- }
-
- int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
-
- if(len < 0) {
- ESP_LOGE(TAG, "recv failed: errno %d", errno);
- break;
- } else {
- rx_buffer[len] = 0;
- ESP_LOGI(TAG, "Received %d bytes from %s:", len, host_ip);
- ESP_LOGI(TAG, "%s", rx_buffer);
- double voltage = 0.0;
-
- if(strstr(rx_buffer, "RED")) voltage = 2.41;
- else if(strstr(rx_buffer, "GREEN")) voltage = 1.98;
- else if(strstr(rx_buffer, "BLUE")) voltage = 1.65;
- else if(strstr(rx_buffer, "YELLOW")) voltage = 1.11;
- else if(strstr(rx_buffer, "PURPLE")) voltage = 0.82;
- else if(strstr(rx_buffer, "WHITE")) voltage = 0.38;
- xQueueSend(adc_queue, (double *)&voltage, 0);
- }
- vTaskDelay(2000 / portTICK_PERIOD_MS);
- }
-
- if (sock != -1) {
- ESP_LOGE(TAG, "Shutting down socket and restarting...");
- shutdown(sock, 0);
- close(sock);
- }
- }
- vTaskDelete(NULL);
- }
|