当前位置: 首页>移动开发>正文

esp32s3 板载led esp32c3

参照乐鑫官方教程,在ESP32C3上实现了CoAP服务器,代码如下(基于IDF):

/*CoAP*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "wifi_provisioning/manager.h"
#include "wifi_provisioning/scheme_softap.h"
#include "socket.h"
#include "esp_http_server.h"
#include "coap3/coap.h"
/*宏定义*/
#define ERASE_NVS 0
// 清除储存的wifi密码->0: 沿用上次的WIFI信息进行连接; 1: 清除WIFI信息,使用SOFTAP一键配网进行新链接
/*函数声明*/
void WIFI_CALLBACK_FUN(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data); // 事件队列回调函数
void wifi_connect(void);                                                                                          // WIFI连接处理函数
void uri_get_req(coap_resource_t *resource, coap_session_t *session, 
                 const coap_pdu_t *request, const coap_string_t *str_t,
                 coap_pdu_t *response);                                      //相应客户端的GET请求
void uri_post_req(coap_resource_t *resource, coap_session_t *session, 
                 const coap_pdu_t *request, const coap_string_t *str_t,
                 coap_pdu_t *response);                                      //相应客户端的POST请求

/*全局变量*/
int LINK_WIFI_SUCCESS = 255;
/***************************************************************************************************************/
/*MAIN函数*/
void app_main(void)
{
    wifi_connect(); // 连接wifi
    /*1. 创建coap套接字*/
    coap_address_t addr;
    coap_address_init(&addr);                  //仅执行了addr.size=28
    addr.addr.sin.sin_family = AF_INET;
    int set_ip = 0;
    inet_aton("0.0.0.0", &set_ip);
    addr.addr.sin.sin_addr.s_addr = set_ip;
    addr.addr.sin.sin_port = htons(5683);
    /*2. 创建coap ctx*/
    coap_context_t *ctx = NULL;                //ctx结构体包含coap状态和属性
    ctx = coap_new_context(&addr);             //创建ctx对象
    /*3. 给资源提供URI*/
    coap_resource_t * resource = NULL;
    coap_str_const_t uri_path =
    {
        .length = strlen("ok"),
        .s = (const uint8_t *)"ok"
    };
    resource = coap_resource_init(&uri_path, 0);
    /*4. 注册URI*/
    coap_register_request_handler(resource, COAP_REQUEST_CODE_GET, uri_get_req);
    //coap_register_handler(resource, COAP_REQUEST_CODE_GET, uri_get_req);  //OLD
    //coap_register_handler(resource, COAP_REQUEST_CODE_POST, uri_post_req);//OLD
    coap_register_request_handler(resource, COAP_REQUEST_CODE_POST, uri_post_req);
    /*5. 设置COAP GET资源可见-订阅模式*/
    coap_resource_set_get_observable(resource, 1);
    /*6. 将资源添加进(注册)ctx*/
    coap_add_resource(ctx, resource);
    /*7.监听,等待接收数据*/
    while(1)
    {
        int ret = coap_io_process(ctx, 1000);
        if(ret == -1)
        {
            printf("ret=-1, 出错!\n");
            goto error_line;
        }
        vTaskDelay(1);
    }
error_line:
    /*end: 释放ctx资源*/
    coap_free_context(ctx);
    while(1)
    {
        printf("错误,空闲线程!\n");
        vTaskDelay(500);
    }
}
/*响应客户端的POST请求回调函数*/
void uri_post_req(coap_resource_t *resource, coap_session_t *session, 
                 const coap_pdu_t *request, const coap_string_t *str_t,
                 coap_pdu_t *response)
{ 
    const uint8_t *recv_dat = NULL;
    size_t dt_len = 0;
    char recv_buf[100] = {0};
    coap_resource_notify_observers(resource, NULL);     //
    int ret = coap_get_data(request, &dt_len, &recv_dat);
    if(ret == 1)
    {
        strncpy(recv_buf, (char *)recv_dat, dt_len);
        recv_buf[dt_len] = 'dependencies:
  espressif/coap: "^4.3.0"';                    //字符串结尾标志
        printf("CoAP收到的POST数据为:%s\n", recv_buf);
        //coap_send_ack(session, response);
        //response->code = COAP_RESPONSE_CODE_CHANGED; //COAP_RESPONSE_CODE(204);
    }
    else
    {
        printf("CoAP接收POST错误!\n");
    }
}
/*响应客户端的GET请求回调函数*/
int cnt = 0;
void uri_get_req(coap_resource_t *resource, coap_session_t *session, 
                 const coap_pdu_t *request, const coap_string_t *str_t,
                coap_pdu_t *response)
{
    char get_buf[15] = "Hello CoAP!";
    cnt ++;
    itoa(cnt, &get_buf[11], 10);
    coap_add_data_blocked_response(request, response, COAP_MEDIATYPE_TEXT_PLAIN, 0, sizeof(get_buf), (const uint8_t *)get_buf);
                                                                                            //COAP_MEDIATYPE_TEXT_PLAIN->0-TEXT格式
    printf("CoAP回应GET数据为:%s\n", get_buf);
}    
/**********************************************************************************************/
/*回调函数*/
int dis_cnt = 0;
void WIFI_CALLBACK_FUN(void *event_handler_arg, esp_event_base_t eb, int32_t ei, void *event_data)
{
    if (eb == WIFI_EVENT)
    {
        if (ei == WIFI_EVENT_STA_START)
        {
            esp_wifi_connect(); // 开始连接WIFI
            printf("正在连接WIFI!\n");
        }
        if (ei == WIFI_EVENT_STA_DISCONNECTED)
        {
            dis_cnt ++;
            if(dis_cnt < 10)
            {
                vTaskDelay(100);
                esp_wifi_connect();
                printf("正在进行第%d次重新连接...\n", dis_cnt);
            }
            else
            {
                nvs_flash_erase();  //清除旧密码
                nvs_flash_init();
                printf("自动连接失败,正在启动SOFTAP配网服务!\n");
                const char *pop = "abcd1234";
                const char *wifi_name = "SOFTAP_PROV_MGR_PROB";
                const char *wifi_key = "12345678";
                wifi_prov_mgr_start_provisioning(WIFI_PROV_SECURITY_1, pop, wifi_name, wifi_key);
                wifi_prov_mgr_wait();
                wifi_prov_mgr_deinit();
                printf("Provisioning服务结束,连接WIFI成功!\n");
            }
        }
    }
    if(eb == WIFI_PROV_EVENT && ei == WIFI_PROV_CRED_FAIL)
    {
        printf("配网失败,正在重试!\n");
        nvs_flash_erase();  //清除旧密码
        nvs_flash_init();
        printf("自动连接失败,正在启动SOFTAP配网服务!\n");
        const char *pop = "abcd1234";
        const char *wifi_name = "SOFTAP_PROV_MGR_PROB";
        const char *wifi_key = "12345678";
        wifi_prov_mgr_start_provisioning(WIFI_PROV_SECURITY_1, pop, wifi_name, wifi_key);
        wifi_prov_mgr_wait();
        wifi_prov_mgr_deinit();
        printf("Provisioning服务结束,连接WIFI成功!\n");
    }
    if (eb == IP_EVENT && ei == IP_EVENT_STA_GOT_IP)
    {
        printf("WIFI连接成功!\n");
        ip_event_got_ip_t *sta_ip = (ip_event_got_ip_t *)event_data;
        printf("本机IP地址为: " IPSTR "\n", IP2STR(&sta_ip->ip_info.ip));
        LINK_WIFI_SUCCESS = 0;  //已经连接成功标识清零
        
    }
}

/*连接WIFI*/
void wifi_connect(void)
{
    nvs_flash_init();
#if ERASE_NVS != 0
    nvs_flash_erase();
    nvs_flash_init();
#endif
    esp_event_loop_create_default(); // 创建默认事件队列
    esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, WIFI_CALLBACK_FUN, NULL, NULL);
    esp_event_handler_instance_register(WIFI_PROV_EVENT, WIFI_PROV_CRED_FAIL, WIFI_CALLBACK_FUN, NULL, NULL);
    esp_netif_init();                    // 初始化网卡
    esp_netif_create_default_wifi_ap();  // 创建默认网卡ap
    esp_netif_create_default_wifi_sta(); // 创建默认网卡sta
    wifi_init_config_t esp_wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&esp_wifi_init_config); // 初始化WIFI功能
    /*softAP配网*/
    wifi_prov_mgr_config_t wifi_prov_mgr_config_t =
    {
            .scheme = wifi_prov_scheme_softap,
            .app_event_handler = WIFI_PROV_EVENT_HANDLER_NONE
    };
    wifi_prov_mgr_init(wifi_prov_mgr_config_t);
    bool wifi_prov_mgr_diag = false;
    wifi_prov_mgr_is_provisioned(&wifi_prov_mgr_diag);
    if (wifi_prov_mgr_diag == false)
    {
        const char *pop = "abcd1234";
        const char *wifi_name = "SOFTAP_PROV_MGR_PROB";
        const char *wifi_key = "12345678";
        wifi_prov_mgr_start_provisioning(WIFI_PROV_SECURITY_1, pop, wifi_name, wifi_key);
        wifi_prov_mgr_wait();
        wifi_prov_mgr_deinit();
        printf("Provisioning服务结束,连接WIFI成功!\n");
    }
    else
    {
        esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_STA_START, WIFI_CALLBACK_FUN, NULL, NULL);        // 注册WIFI开启事件
        esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, WIFI_CALLBACK_FUN, NULL, NULL);    // 注册WIFI连接事件
        esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, WIFI_CALLBACK_FUN, NULL, NULL); // 注册WIFI连接失败事件
        esp_wifi_start();
    }
    esp_wifi_set_ps(WIFI_PS_NONE); // 关闭WIFI的省电模式
    while(LINK_WIFI_SUCCESS)   //等到WIFIF连接成功
    {
        vTaskDelay(1);         //防止看门狗复位
    }
}

但是注意:创建项目后包含头文件"coap3/coap.h"会出现错误,是因为Coap相关库文件未引入,引入方法是在项目main文件夹下面创建文件"idf_component.yml",并在文件中添加以下代码:

https://libcoap.net/doc/reference/4.2.0/resource_8c.html#a44d6a5ed6425069699a01f7e8ed72579

调试:使用谷歌浏览器,在谷歌浏览器中安装Cooper插件,使用插件可以进行调试。

下载地址:https://github.com/mkovatsc/Copper4Cr.git

或者在本页附件也能下载。

最后,附上coap函数库学习地址:


https://www.xamrdz.com/mobile/47t1963161.html

相关文章: