1689|1

155

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【建筑施工监测与安防系统】七、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;//flags variable
  • int                aita_retry_num = 0;   //record retry times
  • 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) {
  •         //By author. if esp32 is in STA mode, start trying to connect AP
  •         esp_wifi_connect();
  •     } else if(event_base==WIFI_EVENT && event_id==WIFI_EVENT_STA_DISCONNECTED) {
  •         //By author. if esp32 is disconnected, retry to connect
  •         if(aita_retry_num < AITA_WIFI_MAX_RETRY) {
  •             esp_wifi_connect();
  •             aita_retry_num++;
  •             ESP_LOGI(TAG, "retry to connect to the AP");
  •         } else {
  •             //By author. retry max times, then set FAIL flag bit
  •             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) {
  •         //By author. if esp32 gets IP, set connected flag bit
  •         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) {
  •     //By author. create event group for wifi events
  •     aita_wifi_event_group = xEventGroupCreate();
  •     //By author. initialize tcp stack, creates default wifi STA
  •     ESP_ERROR_CHECK(esp_netif_init());
  •     ESP_ERROR_CHECK(esp_event_loop_create_default());
  •     esp_netif_create_default_wifi_sta();
  •     //By author. initialize wifi driver interface
  •     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  •     ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  •     //By author. register wifi event
  •     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));
  •     //By author. connect AP
  •     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.");
  •     //By author. wait for flag
  •     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");
  •     }
  •     //By author. unregister wifi event
  •     /* The event will not be processed after unregister */
  •     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);
  •             // Error occurred during receiving
  •             if(len < 0) {
  •                 ESP_LOGE(TAG, "recv failed: errno %d", errno);
  •                 break;
  •             } else {
  •                 rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
  •                 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);
  • }

 

最新回复

感谢分享wifi联网以及socket数据的发送。看来进度不错呀!   详情 回复 发表于 2022-8-21 23:22
点赞 关注
 
 

回复
举报

7196

帖子

11

TA的资源

版主

沙发
 

感谢分享wifi联网以及socket数据的发送。看来进度不错呀!

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播 | AI之眼——安森美图像传感器 报名中
直播时间:2025年4月25日(周五)上午10:00-11:30
直播主题:AI之眼——安森美图像传感器
报名观看直播、直播间提问、填写问卷均有机会获得精美礼品!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 15

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表