espnow-流程篇

由于老是记不住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;
        }
    }
}
}

 

posted @ 2023-11-09 16:30  悠闲的小莫  阅读(26)  评论(2编辑  收藏  举报