首页 > 其他分享 >espnow-流程篇

espnow-流程篇

时间:2023-11-09 16:45:52浏览次数:37  
标签:ESP recv espnow param send peer data 流程

由于老是记不住espnow的流程,写一篇博客记一下:

espnow_init

这个函数主要是对各个函数进行一个调用,其实没什么好说的(原来是main函数)

example_wifi_init

 对wifi的一个初始化,进行默认的初始化

example_espnow_init

这个是重头戏

在此处用队列形式传递数据,所以要初始化队列

此处则是对espnow的初始化以及对发送和接收函数回调函数进行一个注册

在这块可以看到发送和接收完后会有什么操作

 

这个就是添加密钥什么的,就是解码加密的东西

接下来就是通过添加要发送的列表添加信息

然后就开始准备发送的数据的数据头

最后通过添加数据的准备和创建任务,基本完成

example_espnow_task

这个也是比较重要的一环,但其实也没什么好说的了,懂了之前的准备函数这个就是为发送完后的回调做准备的,下面是我注释过的函数:

static void example_espnow_task(void *pvParameter)
{
    example_espnow_event_t evt;
    uint8_t dat[15];         // 第一位为0的时候发送的时候结束进程
    uint8_t recv_state = 0;  // 判断接收数据的广播还是单独的,判断接收到的是第几个
    uint16_t recv_seq = 0;   //收到的个数
    int recv_magic = 0;      // 判断接收数据的优先级
    bool is_broadcast = false;
    bool is_link = false;
    int ret;

    vTaskDelay(1000 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "Start sending broadcast data");

    /* Start sending broadcast ESPNOW data. */
    example_espnow_send_param_t *send_param = (example_espnow_send_param_t *)pvParameter;
    if (esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len) != ESP_OK) {
        ESP_LOGE(TAG, "Send error");
        example_espnow_deinit(send_param);
        vTaskDelete(NULL);
    }

    while (xQueueReceive(s_example_espnow_queue, &evt, portMAX_DELAY) == pdTRUE) {
        switch (evt.id) {
                    {
            case EXAMPLE_ESPNOW_SEND_ED:
            {
                if(is_link == true&&flag_connet==true)
                {
                    memcpy(dat, evt.payload, 15);   // 传入数据
                    memcpy(send_param->dest_mac,example_macs,ESP_NOW_ETH_ALEN);
                    example_espnow_data_prepare(send_param, evt.payload); // 传入数据
                    // ESP_LOGI(TAG, "send data to " MACSTR "", MAC2STR(send_param->dest_mac));
                    // ESP_LOGI("SEND","%x,len%d",esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len),send_param->len);
                    flag_sendding=true;
                    if (esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len) != ESP_OK)
                    {
                        ESP_LOGE(TAG, "Send error1");
                        example_espnow_deinit(send_param);
                        vTaskDelete(NULL);
                    }
                }
                break;
            }
            case EXAMPLE_ESPNOW_SEND_CB:
            {
            flag_sendding=false;
            if (is_link == false)
            {
                example_espnow_event_send_cb_t *send_cb = &evt.info.send_cb;
                is_broadcast = IS_BROADCAST_ADDR(send_cb->mac_addr); // 比较广播地址,要是不一样则为斯波

                //ESP_LOGD(TAG, "Send data to "MACSTR", status1: %d", MAC2STR(send_cb->mac_addr), send_cb->status);

                if (is_broadcast) {
                    send_param->count--;
                    if (send_param->count == 0) {
                        ESP_LOGI(TAG, "Send done");
                        example_espnow_deinit(send_param);
                        send_xbox_move(0x50,0x00,2000);//震动2秒
                        vTaskDelete(NULL);
                    }
                }

                if (!is_broadcast) {
                    ESP_LOGI(TAG, "link success");
                    send_xbox_move(0x50,0x50,2000);//震动2秒
                    is_link = true;
                    break;
                    // example_espnow_deinit(send_param);
                    // vTaskDelete(NULL);
                }



                /* Delay a while before sending the next data. 在发送下一个数据之前延迟一段时间。
                之前的哪个数据帧里面的延迟时间是在这里用的*/
                if (send_param->delay > 0) {
                    vTaskDelay(send_param->delay/portTICK_PERIOD_MS);
                }

                ESP_LOGI(TAG, "send data to "MACSTR"", MAC2STR(send_cb->mac_addr));

                memcpy(send_param->dest_mac, send_cb->mac_addr, ESP_NOW_ETH_ALEN);
                example_espnow_data_prepare(send_param,&recv_seq);

                /* Send the next data after the previous data is sent. */
                if (esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len) != ESP_OK) {
                    ESP_LOGE(TAG, "Send error2");
                    example_espnow_deinit(send_param);
                    vTaskDelete(NULL);
                }
                break;
            }else{
                // ESP_LOGI("espnow", "send success");
                break;
            }
            }
            case EXAMPLE_ESPNOW_RECV_CB:
            {
                example_espnow_event_recv_cb_t *recv_cb = &evt.info.recv_cb;

                ret = example_espnow_data_parse(recv_cb->data, recv_cb->data_len, &recv_state, &recv_seq, &recv_magic,dat);
                free(recv_cb->data);
                //ESP_LOGI("data", "%s", dat); // 此为收到的数据
                if (ret == EXAMPLE_ESPNOW_DATA_BROADCAST&&recv_magic==0) {
                    //ESP_LOGI(TAG, "Receive %dth broadcast data from: "MACSTR", len: %d", recv_seq, MAC2STR(recv_cb->mac_addr), recv_cb->data_len);

                    /* If MAC address does not exist in peer list, add it to peer list. */
                    /*如果对等体列表中没有MAC地址,则将MAC地址添加到对等体列表中,必须是未连接状态并且magic为0*/
                    if (esp_now_is_peer_exist(recv_cb->mac_addr) == false&&flag_connet==false) {
                        // esp_now_peer_info_t *peer = malloc(sizeof(esp_now_peer_info_t));
                        // if (peer == NULL) {
                        //     ESP_LOGE(TAG, "Malloc peer information fail");
                        //     example_espnow_deinit(send_param);
                        //     vTaskDelete(NULL);
                        // }
                        // memset(peer, 0, sizeof(esp_now_peer_info_t));
                        // peer->channel = CONFIG_ESPNOW_CHANNEL;
                        // peer->ifidx = ESPNOW_WIFI_IF;
                        // peer->encrypt = true;
                        // memcpy(peer->lmk, CONFIG_ESPNOW_LMK, ESP_NOW_KEY_LEN);
                        // memcpy(peer->peer_addr, recv_cb->mac_addr, ESP_NOW_ETH_ALEN);
                        // ESP_ERROR_CHECK( esp_now_add_peer(peer) );
                        // free(peer);
                        esp_now_peer_info_t *peer = malloc(sizeof(esp_now_peer_info_t));
                        if (peer == NULL)
                        {
                            ESP_LOGE(TAG, "Malloc peer information fail");
                            example_espnow_deinit(send_param);
                            vTaskDelete(NULL);
                        }
                        memset(peer, 0, sizeof(esp_now_peer_info_t));
                        peer->channel = CONFIG_ESPNOW_CHANNEL;
                        peer->ifidx = ESPNOW_WIFI_IF;
                        peer->encrypt = true;
                        memcpy(peer->lmk, CONFIG_ESPNOW_LMK, ESP_NOW_KEY_LEN);
                        memcpy(peer->peer_addr, recv_cb->mac_addr, ESP_NOW_ETH_ALEN);
                        ESP_ERROR_CHECK(esp_now_add_peer(peer));
                        free(peer);
                        memcpy(example_macs,recv_cb->mac_addr,ESP_NOW_ETH_ALEN);
                        ESP_LOGI("SAVE","SAVING MAC");
                        flag_connet=true;//表示已经对接设备了
                        }

                    /* Indicates that the device has received broadcast ESPNOW data. */
                    /*设备收到广播ESPNOW数据。*/
                    ESP_LOGI("STAT","STATE IS %d",recv_state);
                    if (send_param->state == 0) {
                        send_param->state = 1;
                    }

                    /* If receive broadcast ESPNOW data which indicates that the other device has received
                    * broadcast ESPNOW data and the local magic number is bigger than that in the received
                    * broadcast ESPNOW data, stop sending broadcast ESPNOW data and start sending unicast
                    * ESPNOW data.
                    * *如果接收到广播ESPNOW数据,表示另一台设备已经接收到*广播ESPNOW数据,
                    * 且本地魔术数大于接收到的*广播ESPNOW数据,则停止发送广播ESPNOW数据,开始发送单播数据。
                    */
                    if (recv_state == 1) {//发送回给对面让他确认是否已经存了
                        /* The device which has the bigger magic number sends ESPNOW data, the other one
                         * receives ESPNOW data.
                         */
                        if (send_param->unicast == false && send_param->magic >= recv_magic) {
                    	    ESP_LOGI(TAG, "Start sending unicast data");
                    	    ESP_LOGI(TAG, "send data to "MACSTR"", MAC2STR(recv_cb->mac_addr));

                    	    /* Start sending unicast ESPNOW data. */
                            memcpy(send_param->dest_mac, recv_cb->mac_addr, ESP_NOW_ETH_ALEN);
                            example_espnow_data_prepare(send_param,&recv_seq);
                            if (esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len) != ESP_OK) {
                                ESP_LOGE(TAG, "Send error3");
                                example_espnow_deinit(send_param);
                                vTaskDelete(NULL);
                            }
                            else {
                                send_param->broadcast = false;
                                send_param->unicast = true;
                            }
                        }
                        else if(send_param->unicast == false && send_param->magic <= recv_magic)
                        {
                                send_param->broadcast = false;
                                send_param->unicast = true;
                        }
                    }
                }
                else if (ret == EXAMPLE_ESPNOW_DATA_UNICAST) {
                    //ESP_LOGI(TAG, "Receive %dth unicast data from: "MACSTR", len: %d", recv_seq, MAC2STR(recv_cb->mac_addr), recv_cb->data_len);

                    /* If receive unicast ESPNOW data, also stop sending broadcast ESPNOW data. */
                    send_param->broadcast = false;
                }
                else {
                    ESP_LOGE(TAG, "Receive error data from: "MACSTR"", MAC2STR(recv_cb->mac_addr));
                }
                break;
            }
            default:
                ESP_LOGE(TAG, "Callback type error: %d", evt.id);
                break;
        }
    }
}
}

 

标签:ESP,recv,espnow,param,send,peer,data,流程
From: https://www.cnblogs.com/recodemo/p/17822041.html

相关文章

  • win版本 mysql5.7 解压安装流程
    win版本mysql5.7解压安装流程https://dev.mysql.com/downloads/mysql/5.7.html#downloads1、添加系统变量变量名:MYSQL_HOME变量值:D:\ProgramData\mysql-5.7.44-winx642、编辑my.inimy.ini[mysqld]basedir=D:\ProgramData\mysql-5.7.44-winx64datadir=D:\ProgramData\mysql-5.7.......
  • btmon获取hci数据流程
    btmon获取hci数据流程背景最近在看蓝牙相关的驱动代码,追到hci接收数据处理函数hci_rx_work()(net/bluetooth/hci_core.c),瞄到下面一段代码:C...while((skb=skb_dequeue(&hdev->rx_q))){/*Sendcopytomonitor*/hci_send_to_monitor(hdev,skb);.........
  • 济南申请发明专利需要哪些流程
    济南申请发明专利需要哪些流程恒标知产刘经理 审批程序包括受理、初审、公布、实审以及授权五个阶段。1、受理阶段:如果符合受理条件,专利局将确定申请日给予申请号并且核实过文件清单后,发出受理通知书,通知申请人。2、初步审查阶段:(1)发明名称一般不得超过25个字,特殊情况,化学领域的发......
  • 2023码尚教育接口自动化框架的实现源码分享pytest+allure+jenkins几乎零代码少量的代
    本框架适合对Pytest有大概认识(比如看完X站3天课程的水平),职场新人没有雄厚的资本去参加专业的培训、功能测试转自动化测试、开发转测试的小伙伴们。首先介绍下这个框架的使用,看看是不是你所需要的。第一步、添加模块PY文件,编写接口代码。classTestJuhe: #upwei:fanfanzb2023......
  • 大数据清洗流程
     首先将result.txt文件放到到虚拟机**创建数据库**createdatabasejournal;**切换到数据库**usejournal--建立初始表createtabledata(`ip`stringcomment"城市",`time`stringcomment"时间",`day`stringcomment"天数",`traffic`doublecomment"流量&......
  • 【详细】性能测试的概念、分类、性能指标与流程
    一、性能测试概论1、性能的概念性能:就是软件质量属性中的“效率”特征,效率又可以划分为时间和资源——时间:系统处理用户请求的响应时间——资源:系统运行过程中,系统资源消耗的情况2、性能测试的概念使用自动化工具,模拟不同的场景,对软件各项性能指标进行测试和评估的过程3、性能......
  • shell编程-流程控制
    拓展basename&dirnamebasename命令basename是去除目录后剩下的名字,取文件名例: [root@linux-server~]#temp=/home/temp/1.test[root@linux-server~]#base=`basename$temp`[root@linux-server~]#echo$base1.testdirname是获取目录名 例:[root@linux-server......
  • 医院HIS手术麻醉临床信息管理系统源码 实现术前、术中、术后全流程管理
    手术麻醉系统是一套以数字形式与医院信息系统(如HIS、EMR、LIS、PACS等)和医疗设备等软、硬件集成并获取围手术期相关信息的计算机系统,其核心是对围手术期患者信息自动采集、储存、分析并呈现。该系统通过整合围手术期中病人信息、人员信息、手术信息、物品信息等内容,可提供全套标准......
  • 带您了解 O2OA 流程中的人工活动处理方式
    这次咱们来介绍O2OA(翱途)开发平台流程引擎中的人工活动的处理方式和逻辑,O2OA(翱途) 主要采用拖拽可视化开发的方式完成流程的设计和配置,不需要过多的代码编写,业务人员可以直接进行修改操作。例如,咱们做一个“报销申请”流程,红色框框里的都是人工处理活动。 人工活动......
  • 简单高效!pycharm激活全流程在此!
    不多废话,直接上Pycharm2023.2激活教程第一步:下载Pycharm安装包访问Pycharm官网,下载Pycharm2023.2版本的安装包,链接我就不放了,容易被挂打开页面后,点击Download按钮,等待Pycharm专业版下载完毕。第二步:安装Pycharm2023.2版本如果电脑之前有安装老版本Pycharm,需要......