国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

這篇具有很好參考價值的文章主要介紹了ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

ESP32+idf開發(fā)之藍牙通信入門—ble數(shù)據(jù)收發(fā)(notify)

一、實現(xiàn)功能:

esp32作為藍牙從機,與手機端藍牙調(diào)試助手(如LightBlue)主機進行通信,實現(xiàn)數(shù)據(jù)的收發(fā)功能:

1、收:藍牙調(diào)試助手發(fā)送數(shù)據(jù)控制esp32開發(fā)板led燈的亮滅;

2、發(fā)(notify):esp32將傳感器數(shù)據(jù)(如溫度數(shù)據(jù))主動每隔2s發(fā)送給藍牙調(diào)試助手,實現(xiàn)通知(notify)功能;

二、藍牙BLE概述:

? 1、BLE(低功耗藍牙)采用了client/server (C/S) 架構(gòu)來進行數(shù)據(jù)交互。這里講的C/S架構(gòu)和前面tcp/udp編程時所講的C/S架構(gòu)是相同的。 一般而言藍牙設(shè)備提供服務,因此設(shè)備是server,手機使用設(shè)備提供的服務,因此手機是client。比如藍牙體溫計,它可以提供 “體溫” 數(shù)據(jù)服務,因此是一個server,而手機則可以請求“體溫”數(shù)據(jù)以顯示在手機上,因此手機是一個client。

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

? 中央設(shè)備(主機)即通信的發(fā)起者,只能與外圍設(shè)備通信;外圍設(shè)備(從機)無法啟動通信,只能與中央設(shè)備通信;同一時間外圍設(shè)備只能與一個中央設(shè)備通信;外圍設(shè)備無法與其他外圍設(shè)備通信。

? 2、藍牙協(xié)議棧:

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

? profile 可以理解為一種規(guī)范,建立的藍牙應用任務,藍牙任務實際上分為兩類: 標準藍牙任務規(guī)范 profile(公有任務),非標準藍牙任務規(guī)范 profile(私有任務)。標準藍牙任務規(guī)范 profile:指的是從藍牙特別興趣小組 SIG 的官網(wǎng)上已經(jīng)發(fā)布的 GATT 規(guī)范列表,包括警告通知(alert notification),血壓測量(blood pressure),心率(heart rate),電池(battery)等等。它們都是針對具體的低功耗藍牙的應用實例來設(shè)計的。profile的結(jié)構(gòu)如下:

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

? service即服務:在 BLE 從機中有多個服務,例如:電量信息服務、系統(tǒng)信息服務等;每個 service 中又包含多個 characteristic 特征值;

? characteristic即特征,上面講到: Service通過characteristic對數(shù)據(jù)進行封裝,每個service中又包含多個 characteristic 特征值。一個characteristic包含三種條目:characteristic聲明,characteristic的值以及characteristic的描述符。Characteristic是在GATT規(guī)范中最小的邏輯數(shù)據(jù)單元,由一個Value和多個描述特性的Desciptior組成。實際上,在與藍牙設(shè)備打交道,主要就是讀寫Characteristic的value來完成。

? Attribute 是屬于 ATT屬性層的東西,它是 ATT層 的核心。Attribute其實就是一條一條的數(shù)據(jù)。前面說過,每個藍牙設(shè)備就是用來提供服務的,而服務就是眾多數(shù)據(jù)的合集,這個合集可以稱為數(shù)據(jù)庫,數(shù)據(jù)庫里面每個條目都是一個attribute。Attribute 由以下 4 部分組成:屬性句柄(Attribute Handler)、屬性類型(AttributeType)、屬性值(Attribute Value)、屬性權(quán)限(Attribute Permissions)。

? UUID(universally uniqueidentifier,通用唯一識別碼)是一個軟件構(gòu)建標準,一個合法的UUID,一定是隨機的、全球唯一的。(UUID并不是BLE獨有的概念)上面提到的 service 和 characteristic,都需要一個唯一的uuid來標識。

? GATT (通用屬性配置,Generic Attribute Profile) ,它定義兩個 BLE 設(shè)備通過 Service 和 Characteristic 進行通信;GATT 就是使用了 ATT(Attribute Protocol)協(xié)議,ATT層定義了一個通信的基本框架,數(shù)據(jù)的基本結(jié)構(gòu),以及通信的指令,Service 和 characteristic 就是GATT層定義的, GATT層用來賦予每個數(shù)據(jù)一個具體的內(nèi)涵,讓數(shù)據(jù)變得有結(jié)構(gòu)和意義。一旦兩個設(shè)備建立起了連接,GATT 就開始起作用了,這里需要說明的是,GATT 連接必需先經(jīng)過 GAP 協(xié)議。

? GAP(通用訪問規(guī)范,Generic Access Profile)在用來控制設(shè)備連接和廣播,用于提供藍牙設(shè)備的通用訪問功能,包括設(shè)備發(fā)現(xiàn)、連接、鑒權(quán)、服務發(fā)現(xiàn)等等。GATT是建立連接后通信規(guī)范, 而藍牙是通過GAP建立通信的。GAP 使你的設(shè)備被其他設(shè)備可見,并決定了你的設(shè)備是否可以或者怎樣與合同設(shè)備進行交互。

三、步驟

1、使用模板gatt_server_service_table創(chuàng)建新工程。

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

2、修改藍牙名并不使用默認廣播數(shù)據(jù):

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

3、增加屬性表配置特征值用來描述LED和溫度的相關(guān)信息:(可仿照特征A來寫),同時將相關(guān)的宏定義和相關(guān)保存LED燈狀態(tài)和溫度值的變量進行定義完善。

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

2、獲取得到主機藍牙調(diào)試助手發(fā)來的數(shù)據(jù),并進行判斷,封裝led組件,調(diào)用組件接口驅(qū)動LED亮滅

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

3、收到藍牙主機調(diào)試助手的notify訂閱后創(chuàng)建任務進行溫度數(shù)據(jù)采集并發(fā)送到主機,此處采用溫度數(shù)據(jù)模擬;收到取消notify后則任務刪除。

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

四、完整代碼

gatts_table_creat_demo.c:

/*
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

/****************************************************************************
 *
 * This demo showcases creating a GATT database using a predefined attribute table.
 * It acts as a GATT server and can send adv data, be connected by client.
 * Run the gatt_client demo, the client demo will automatically connect to the gatt_server_service_table demo.
 * Client demo will enable GATT server's notify after connection. The two devices will then exchange
 * data.
 *
 ****************************************************************************/

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"

#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_bt_main.h"
#include "gatts_table_creat_demo.h"
#include "esp_gatt_common_api.h"

#include <led.h>

#define GATTS_TABLE_TAG "GATTS_TABLE_DEMO"

#define PROFILE_NUM 1
#define PROFILE_APP_IDX 0
#define ESP_APP_ID 0x55
#define SAMPLE_DEVICE_NAME "rocket_iot" // 修改藍牙名
#define SVC_INST_ID 0

/* The max length of characteristic value. When the GATT client performs a write or prepare write operation,
 *  the data length must be less than GATTS_DEMO_CHAR_VAL_LEN_MAX.
 */
#define GATTS_DEMO_CHAR_VAL_LEN_MAX 500
#define PREPARE_BUF_MAX_SIZE 1024
#define CHAR_DECLARATION_SIZE (sizeof(uint8_t))

#define ADV_CONFIG_FLAG (1 << 0)
#define SCAN_RSP_CONFIG_FLAG (1 << 1)

static uint8_t adv_config_done = 0;

uint16_t heart_rate_handle_table[HRS_IDX_NB];

typedef struct
{
    uint8_t *prepare_buf;
    int prepare_len;
} prepare_type_env_t;

static prepare_type_env_t prepare_write_env;

// #define CONFIG_SET_RAW_ADV_DATA
#ifdef CONFIG_SET_RAW_ADV_DATA
static uint8_t raw_adv_data[] = {
    /* flags */
    0x02, 0x01, 0x06,
    /* tx power*/
    0x02, 0x0a, 0xeb,
    /* service uuid */
    0x03, 0x03, 0xFF, 0x00,
    /* device name */
    0x0f, 0x09, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D', 'E', 'M', 'O'};
static uint8_t raw_scan_rsp_data[] = {
    /* flags */
    0x02, 0x01, 0x06,
    /* tx power */
    0x02, 0x0a, 0xeb,
    /* service uuid */
    0x03, 0x03, 0xFF, 0x00};

#else
static uint8_t service_uuid[16] = {
    /* LSB <--------------------------------------------------------------------------------> MSB */
    // first uuid, 16bit, [12],[13] is the value
    0xfb,
    0x34,
    0x9b,
    0x5f,
    0x80,
    0x00,
    0x00,
    0x80,
    0x00,
    0x10,
    0x00,
    0x00,
    0xFF,
    0x00,
    0x00,
    0x00,
};

/* The length of adv data must be less than 31 bytes */
static esp_ble_adv_data_t adv_data = {
    .set_scan_rsp = false,
    .include_name = true,
    .include_txpower = true,
    .min_interval = 0x0006, // slave connection min interval, Time = min_interval * 1.25 msec
    .max_interval = 0x0010, // slave connection max interval, Time = max_interval * 1.25 msec
    .appearance = 0x00,
    .manufacturer_len = 0,       // TEST_MANUFACTURER_DATA_LEN,
    .p_manufacturer_data = NULL, // test_manufacturer,
    .service_data_len = 0,
    .p_service_data = NULL,
    .service_uuid_len = sizeof(service_uuid),
    .p_service_uuid = service_uuid,
    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};

// scan response data
static esp_ble_adv_data_t scan_rsp_data = {
    .set_scan_rsp = true,
    .include_name = true,
    .include_txpower = true,
    .min_interval = 0x0006,
    .max_interval = 0x0010,
    .appearance = 0x00,
    .manufacturer_len = 0,       // TEST_MANUFACTURER_DATA_LEN,
    .p_manufacturer_data = NULL, //&test_manufacturer[0],
    .service_data_len = 0,
    .p_service_data = NULL,
    .service_uuid_len = sizeof(service_uuid),
    .p_service_uuid = service_uuid,
    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};
#endif /* CONFIG_SET_RAW_ADV_DATA */

static esp_ble_adv_params_t adv_params = {
    .adv_int_min = 0x20,
    .adv_int_max = 0x40,
    .adv_type = ADV_TYPE_IND,
    .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
    .channel_map = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

struct gatts_profile_inst
{
    esp_gatts_cb_t gatts_cb;
    uint16_t gatts_if;
    uint16_t app_id;
    uint16_t conn_id;
    uint16_t service_handle;
    esp_gatt_srvc_id_t service_id;
    uint16_t char_handle;
    esp_bt_uuid_t char_uuid;
    esp_gatt_perm_t perm;
    esp_gatt_char_prop_t property;
    uint16_t descr_handle;
    esp_bt_uuid_t descr_uuid;
};

static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
                                        esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);

/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
static struct gatts_profile_inst heart_rate_profile_tab[PROFILE_NUM] = {
    [PROFILE_APP_IDX] = {
        .gatts_cb = gatts_profile_event_handler,
        .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
    },
};

/* Service */
static const uint16_t GATTS_SERVICE_UUID_TEST = 0x00FF;
static const uint16_t GATTS_CHAR_UUID_TEST_A = 0xFF01;
static const uint16_t GATTS_CHAR_UUID_TEST_B = 0xFF02;
static const uint16_t GATTS_CHAR_UUID_TEST_C = 0xFF03;
static const uint16_t GATTS_CHAR_UUID_TEST_LED = 0xFF04;
static const uint16_t GATTS_CHAR_UUID_TEST_TEMP = 0xFF05;

static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
static const uint8_t char_prop_write = ESP_GATT_CHAR_PROP_BIT_WRITE;
static const uint8_t char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
static const uint8_t char_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
static const uint8_t heart_measurement_ccc[2] = {0x00, 0x00};
static const uint8_t char_value[4] = {0x11, 0x22, 0x33, 0x44};
static const uint8_t led_value[1] = {0x00};
static const uint8_t temp_value[1] = {0x00};

/* Full Database Description - Used to add attributes into the database */
static const esp_gatts_attr_db_t gatt_db[HRS_IDX_NB] =
    {
        // Service Declaration
        [IDX_SVC] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ, sizeof(uint16_t), sizeof(GATTS_SERVICE_UUID_TEST), (uint8_t *)&GATTS_SERVICE_UUID_TEST}},

        /* Characteristic Declaration */
        [IDX_CHAR_A] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},

        /* Characteristic Value */
        [IDX_CHAR_VAL_A] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_A, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},

        /* Client Characteristic Configuration Descriptor */
        [IDX_CHAR_CFG_A] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, sizeof(uint16_t), sizeof(heart_measurement_ccc), (uint8_t *)heart_measurement_ccc}},

        /* Characteristic Declaration */
        [IDX_CHAR_LED] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},

        /* Characteristic Value */
        [IDX_CHAR_VAL_LED] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_LED, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(led_value), (uint8_t *)led_value}},

        /* Characteristic Declaration */
        [IDX_CHAR_TEMP] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}},

        /* Characteristic Value */
        [IDX_CHAR_VAL_TEMP] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_TEMP, ESP_GATT_PERM_READ, GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(temp_value), (uint8_t *)temp_value}},

        /* Client Characteristic Configuration Descriptor */
        [IDX_CHAR_CFG_TEMP] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, sizeof(uint16_t), sizeof(heart_measurement_ccc), (uint8_t *)heart_measurement_ccc}},

        /* Characteristic Declaration */
        [IDX_CHAR_B] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read}},

        /* Characteristic Value */
        [IDX_CHAR_VAL_B] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_B, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},

        /* Characteristic Declaration */
        [IDX_CHAR_C] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_write}},

        /* Characteristic Value */
        [IDX_CHAR_VAL_C] =
            {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_C, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},

};

static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event)
    {
#ifdef CONFIG_SET_RAW_ADV_DATA
    case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
        adv_config_done &= (~ADV_CONFIG_FLAG);
        if (adv_config_done == 0)
        {
            esp_ble_gap_start_advertising(&adv_params);
        }
        break;
    case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
        adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
        if (adv_config_done == 0)
        {
            esp_ble_gap_start_advertising(&adv_params);
        }
        break;
#else
    case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
        adv_config_done &= (~ADV_CONFIG_FLAG);
        if (adv_config_done == 0)
        {
            esp_ble_gap_start_advertising(&adv_params);
        }
        break;
    case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
        adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
        if (adv_config_done == 0)
        {
            esp_ble_gap_start_advertising(&adv_params);
        }
        break;
#endif
    case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
        /* advertising start complete event to indicate advertising start successfully or failed */
        if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "advertising start failed");
        }
        else
        {
            ESP_LOGI(GATTS_TABLE_TAG, "advertising start successfully");
        }
        break;
    case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
        if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "Advertising stop failed");
        }
        else
        {
            ESP_LOGI(GATTS_TABLE_TAG, "Stop adv successfully\n");
        }
        break;
    case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
                 param->update_conn_params.status,
                 param->update_conn_params.min_int,
                 param->update_conn_params.max_int,
                 param->update_conn_params.conn_int,
                 param->update_conn_params.latency,
                 param->update_conn_params.timeout);
        break;
    default:
        break;
    }
}

void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
    ESP_LOGI(GATTS_TABLE_TAG, "prepare write, handle = %d, value len = %d", param->write.handle, param->write.len);
    esp_gatt_status_t status = ESP_GATT_OK;
    if (prepare_write_env->prepare_buf == NULL)
    {
        prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
        prepare_write_env->prepare_len = 0;
        if (prepare_write_env->prepare_buf == NULL)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "%s, Gatt_server prep no mem", __func__);
            status = ESP_GATT_NO_RESOURCES;
        }
    }
    else
    {
        if (param->write.offset > PREPARE_BUF_MAX_SIZE)
        {
            status = ESP_GATT_INVALID_OFFSET;
        }
        else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE)
        {
            status = ESP_GATT_INVALID_ATTR_LEN;
        }
    }
    /*send response when param->write.need_rsp is true */
    if (param->write.need_rsp)
    {
        esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
        if (gatt_rsp != NULL)
        {
            gatt_rsp->attr_value.len = param->write.len;
            gatt_rsp->attr_value.handle = param->write.handle;
            gatt_rsp->attr_value.offset = param->write.offset;
            gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
            memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
            esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
            if (response_err != ESP_OK)
            {
                ESP_LOGE(GATTS_TABLE_TAG, "Send response error");
            }
            free(gatt_rsp);
        }
        else
        {
            ESP_LOGE(GATTS_TABLE_TAG, "%s, malloc failed", __func__);
        }
    }
    if (status != ESP_GATT_OK)
    {
        return;
    }
    memcpy(prepare_write_env->prepare_buf + param->write.offset,
           param->write.value,
           param->write.len);
    prepare_write_env->prepare_len += param->write.len;
}

void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
    if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC && prepare_write_env->prepare_buf)
    {
        esp_log_buffer_hex(GATTS_TABLE_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
    }
    else
    {
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATT_PREP_WRITE_CANCEL");
    }
    if (prepare_write_env->prepare_buf)
    {
        free(prepare_write_env->prepare_buf);
        prepare_write_env->prepare_buf = NULL;
    }
    prepare_write_env->prepare_len = 0;
}

TaskHandle_t *pTask = NULL;
volatile bool notify_flag = false;
static void get_temp(void *arg)
{
    while (1)
    {
        if (notify_flag == true)
        {
            uint8_t temp = 20 + rand() % 11;
            esp_ble_gatts_set_attr_value(heart_rate_handle_table[IDX_CHAR_VAL_TEMP], 1, &temp);
            esp_ble_gatts_send_indicate(heart_rate_profile_tab[0].gatts_if, heart_rate_profile_tab[0].conn_id,
                                                        heart_rate_handle_table[IDX_CHAR_VAL_TEMP], 1, &temp, false);
        }else{
            vTaskDelete(NULL);
        }
        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}
static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    switch (event)
    {
    case ESP_GATTS_REG_EVT:
    {
        esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
        if (set_dev_name_ret)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "set device name failed, error code = %x", set_dev_name_ret);
        }
#ifdef CONFIG_SET_RAW_ADV_DATA
        esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
        if (raw_adv_ret)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret);
        }
        adv_config_done |= ADV_CONFIG_FLAG;
        esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data));
        if (raw_scan_ret)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret);
        }
        adv_config_done |= SCAN_RSP_CONFIG_FLAG;
#else
        // config adv data
        esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);
        if (ret)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "config adv data failed, error code = %x", ret);
        }
        adv_config_done |= ADV_CONFIG_FLAG;
        // config scan response data
        ret = esp_ble_gap_config_adv_data(&scan_rsp_data);
        if (ret)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "config scan response data failed, error code = %x", ret);
        }
        adv_config_done |= SCAN_RSP_CONFIG_FLAG;
#endif
        esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab(gatt_db, gatts_if, HRS_IDX_NB, SVC_INST_ID);
        if (create_attr_ret)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "create attr table failed, error code = %x", create_attr_ret);
        }
    }
    break;
    case ESP_GATTS_READ_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_READ_EVT");
        break;
    case ESP_GATTS_WRITE_EVT:
        if (!param->write.is_prep)
        {
            // the data length of gattc write  must be less than GATTS_DEMO_CHAR_VAL_LEN_MAX.
            ESP_LOGI(GATTS_TABLE_TAG, "GATT_WRITE_EVT, handle = %d, value len = %d, value :", param->write.handle, param->write.len);
            esp_log_buffer_hex(GATTS_TABLE_TAG, param->write.value, param->write.len);
            if (heart_rate_handle_table[IDX_CHAR_VAL_LED] == param->write.handle)
            {
                ESP_LOGI(GATTS_TABLE_TAG, "write:0x%x", param->write.value[0]);
                if (param->write.value[0] == 0x00)
                {
                    led_off(); // 收到數(shù)據(jù)0x00關(guān)燈
                }
                else if (param->write.value[0] == 0x01)
                {
                    led_on(); // 收到數(shù)據(jù)0x01開燈
                }
            }
            if (heart_rate_handle_table[IDX_CHAR_CFG_TEMP] == param->write.handle && param->write.len == 2)
            {
                uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
                if (descr_value == 0x0001)
                {
                    ESP_LOGI(GATTS_TABLE_TAG, "notify enable");
                    xTaskCreate(get_temp, "get temp", 8192, NULL, 10, pTask);
                    notify_flag=true;
                    // ESP_LOGI(GATTS_TABLE_TAG, "notify enable");
                    // uint8_t notify_data[15];
                    // for (int i = 0; i < sizeof(notify_data); ++i)
                    // {
                    //     notify_data[i] = i % 0xff;
                    // }
                    // // the size of notify_data[] need less than MTU size
                    // esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, heart_rate_handle_table[IDX_CHAR_VAL_A],
                    //                             sizeof(notify_data), notify_data, false);
                }
                else if (descr_value == 0x0002)
                {
                    ESP_LOGI(GATTS_TABLE_TAG, "indicate enable");
                    uint8_t indicate_data[15];
                    for (int i = 0; i < sizeof(indicate_data); ++i)
                    {
                        indicate_data[i] = i % 0xff;
                    }
                    // the size of indicate_data[] need less than MTU size
                    esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, heart_rate_handle_table[IDX_CHAR_VAL_A],
                                                sizeof(indicate_data), indicate_data, true);
                }
                else if (descr_value == 0x0000)
                {
                    ESP_LOGI(GATTS_TABLE_TAG, "notify/indicate disable ");
                    notify_flag=false;
                    //vTaskDelete(pTask);
                }
                else
                {
                    ESP_LOGE(GATTS_TABLE_TAG, "unknown descr value");
                    esp_log_buffer_hex(GATTS_TABLE_TAG, param->write.value, param->write.len);
                }
            }
            /* send response when param->write.need_rsp is true*/
            if (param->write.need_rsp)
            {
                esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
            }
        }
        else
        {
            /* handle prepare write */
            example_prepare_write_event_env(gatts_if, &prepare_write_env, param);
        }
        break;
    case ESP_GATTS_EXEC_WRITE_EVT:
        // the length of gattc prepare write data must be less than GATTS_DEMO_CHAR_VAL_LEN_MAX.
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
        example_exec_write_event_env(&prepare_write_env, param);
        break;
    case ESP_GATTS_MTU_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
        break;
    case ESP_GATTS_CONF_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONF_EVT, status = %d, attr_handle %d", param->conf.status, param->conf.handle);
        break;
    case ESP_GATTS_START_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
        break;
    case ESP_GATTS_CONNECT_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT, conn_id = %d", param->connect.conn_id);
        esp_log_buffer_hex(GATTS_TABLE_TAG, param->connect.remote_bda, 6);
        esp_ble_conn_update_params_t conn_params = {0};
        memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
        /* For the iOS system, please refer to Apple official documents about the BLE connection parameters restrictions. */
        conn_params.latency = 0;
        conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms
        conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
        conn_params.timeout = 400;  // timeout = 400*10ms = 4000ms
        heart_rate_profile_tab[0].conn_id = param->connect.conn_id;
        // start sent the update connection parameters to the peer device.
        esp_ble_gap_update_conn_params(&conn_params);
        break;
    case ESP_GATTS_DISCONNECT_EVT:
        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT, reason = 0x%x", param->disconnect.reason);
        esp_ble_gap_start_advertising(&adv_params);
        break;
    case ESP_GATTS_CREAT_ATTR_TAB_EVT:
    {
        if (param->add_attr_tab.status != ESP_GATT_OK)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "create attribute table failed, error code=0x%x", param->add_attr_tab.status);
        }
        else if (param->add_attr_tab.num_handle != HRS_IDX_NB)
        {
            ESP_LOGE(GATTS_TABLE_TAG, "create attribute table abnormally, num_handle (%d) \
                        doesn't equal to HRS_IDX_NB(%d)",
                     param->add_attr_tab.num_handle, HRS_IDX_NB);
        }
        else
        {
            ESP_LOGI(GATTS_TABLE_TAG, "create attribute table successfully, the number handle = %d\n", param->add_attr_tab.num_handle);
            memcpy(heart_rate_handle_table, param->add_attr_tab.handles, sizeof(heart_rate_handle_table));
            esp_ble_gatts_start_service(heart_rate_handle_table[IDX_SVC]);
        }
        break;
    }
    case ESP_GATTS_STOP_EVT:
    case ESP_GATTS_OPEN_EVT:
    case ESP_GATTS_CANCEL_OPEN_EVT:
    case ESP_GATTS_CLOSE_EVT:
    case ESP_GATTS_LISTEN_EVT:
    case ESP_GATTS_CONGEST_EVT:
    case ESP_GATTS_UNREG_EVT:
    case ESP_GATTS_DELETE_EVT:
    default:
        break;
    }
}

static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{

    /* If event is register event, store the gatts_if for each profile */
    if (event == ESP_GATTS_REG_EVT)
    {
        if (param->reg.status == ESP_GATT_OK)
        {
            heart_rate_profile_tab[PROFILE_APP_IDX].gatts_if = gatts_if;
        }
        else
        {
            ESP_LOGE(GATTS_TABLE_TAG, "reg app failed, app_id %04x, status %d",
                     param->reg.app_id,
                     param->reg.status);
            return;
        }
    }
    do
    {
        int idx;
        for (idx = 0; idx < PROFILE_NUM; idx++)
        {
            /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
            if (gatts_if == ESP_GATT_IF_NONE || gatts_if == heart_rate_profile_tab[idx].gatts_if)
            {
                if (heart_rate_profile_tab[idx].gatts_cb)
                {
                    heart_rate_profile_tab[idx].gatts_cb(event, gatts_if, param);
                }
            }
        }
    } while (0);
}

void app_main(void)
{
    esp_err_t ret;

    led_init();

    /* Initialize NVS. */
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    ret = esp_bluedroid_init();
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    ret = esp_bluedroid_enable();
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    ret = esp_ble_gatts_register_callback(gatts_event_handler);
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "gatts register error, error code = %x", ret);
        return;
    }

    ret = esp_ble_gap_register_callback(gap_event_handler);
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "gap register error, error code = %x", ret);
        return;
    }

    ret = esp_ble_gatts_app_register(ESP_APP_ID);
    if (ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "gatts app register error, error code = %x", ret);
        return;
    }

    esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
    if (local_mtu_ret)
    {
        ESP_LOGE(GATTS_TABLE_TAG, "set local  MTU failed, error code = %x", local_mtu_ret);
    }
}

組件led相關(guān)代碼有:led.c

#include <stdio.h>
#include "led.h"
#include<driver/gpio.h>


void led_init(){
    gpio_config_t cfg={
        .pin_bit_mask=1<<LED_PIN,
        .mode=GPIO_MODE_OUTPUT,
        .intr_type=GPIO_INTR_DISABLE,
        .pull_up_en=GPIO_PULLUP_DISABLE,
        .pull_down_en=GPIO_PULLDOWN_DISABLE,
    };
    ESP_ERROR_CHECK(gpio_config(&cfg));
}
void led_on(){
    ESP_ERROR_CHECK(gpio_set_level(LED_PIN,1));
}
void led_off(){
    ESP_ERROR_CHECK(gpio_set_level(LED_PIN,0));
}

led.h

#ifndef __LED_H__
#define __LED_H__

#define LED_PIN GPIO_NUM_2

void led_init();
void led_on();
void led_off();

#endif

五、測試

1、控制led燈測試,默認不亮,藍牙調(diào)試APP發(fā)送0x01,esp燈亮;發(fā)送0x00,led燈滅。

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

2、調(diào)試助手APP點擊notify開關(guān)監(jiān)聽ESP32發(fā)來的溫度數(shù)據(jù)并16進制顯示,關(guān)閉后則停止,同時esp32終端打印相關(guān)信息。

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)

ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)文章來源地址http://www.zghlxwxcb.cn/news/detail-480313.html

到了這里,關(guān)于ESP32+idf開發(fā)—藍牙通信入門之ble數(shù)據(jù)收發(fā)(notify)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 入門小白:STM32hal庫實現(xiàn)ESP8266與手機通信(不定長數(shù)據(jù)收發(fā)和ESP8266使用的一些問題)

    入門小白:STM32hal庫實現(xiàn)ESP8266與手機通信(不定長數(shù)據(jù)收發(fā)和ESP8266使用的一些問題)

    目錄 前言 一、stm32cubeMX的串口配置 二、空閑中斷+dma接收 三、ESP8266.c和ESP8266.h ESP8266.h ESP8266.c 注意事項 四、與手機通信例程 步驟: ?例程代碼main.c 運行結(jié)果 五、相關(guān)問題 總結(jié) 相關(guān)的app和源碼 ? ? ? ? 前提: 1.掌握串口通信和ESP8266的使用方法 串口通信:單片機串口通信

    2024年02月07日
    瀏覽(25)
  • 006.合宙ESP32-C3+藍牙調(diào)試器通過BLE發(fā)送接收數(shù)據(jù)教程

    006.合宙ESP32-C3+藍牙調(diào)試器通過BLE發(fā)送接收數(shù)據(jù)教程

    在平衡小車制作過程中,需要對KP/KD/KSP/KSI等PID系數(shù)進行調(diào)試,而平衡小車無法通過USB等進行有線調(diào)試,而ESP32-C3自帶藍牙+WIFI,使用WIFI比較吃算力,故選擇通過藍牙進行調(diào)參,同時能夠?qū)ngle/Encoder/PWM等數(shù)據(jù)回傳至手機端進行查看。 前期通過查找資料,發(fā)現(xiàn)合宙ESP32-C3自帶藍

    2024年02月03日
    瀏覽(24)
  • ESP-IDF + Vscode ESP32 開發(fā)環(huán)境搭建以及開發(fā)入門

    ESP-IDF + Vscode ESP32 開發(fā)環(huán)境搭建以及開發(fā)入門

    創(chuàng)作不易,轉(zhuǎn)載請注明出處! Tips: 雖然筆者采用的是Linux開發(fā)環(huán)境,但是Windows開發(fā)環(huán)境的亦可閱讀,所述內(nèi)容與系統(tǒng)關(guān)聯(lián)性不大,尤其是后文介紹的如何將自己的文件加入到工程,解決頭文件找不到等問題,無論哪種系統(tǒng)均會存在。 Tips: 最近更新了一篇windows下搭建的,大家

    2024年02月02日
    瀏覽(27)
  • ESP32經(jīng)典藍牙和BLE的使用 (基于Arduino)

    ESP32經(jīng)典藍牙和BLE的使用 (基于Arduino)

    經(jīng)典藍牙串口通信 該程序效果如下 ESP32完成初始化后生成一個藍牙信號 手機通過藍牙串口發(fā)送字符 B ,LED點亮 手機通過藍牙串口發(fā)送字符 A ,LED熄滅 低功耗藍牙 BLE (常用) BLE GATT協(xié)議 GATT全稱Generic Attribute Profile, GATT 代表通用屬性,它定義了暴露給連接的BLE設(shè)備的分層數(shù)據(jù)結(jié)

    2024年02月01日
    瀏覽(58)
  • MicroPython開發(fā)ESP32入門筆記 -- 藍牙篇

    MicroPython開發(fā)ESP32入門筆記 -- 藍牙篇

    博主之前學習了用C語言去開發(fā)了51單片機,雖然沒有將各種外設(shè)和傳感器都玩遍,但博主基本將一些重要的外設(shè)和傳感器通過原理學習加小項目實驗的方式比較深入地玩了一下。眾所周知,51單片機是相對底層的,用來開發(fā)一些大項目的效率會比較低,所以我們很有必要學習

    2023年04月19日
    瀏覽(23)
  • ESP32 IDF iic通信( 已驗證) C語言

    關(guān)于iic原理建議B站自己看視頻去, 然后本文主要實現(xiàn)了esp32的初始化, 寫地址, 寫數(shù)據(jù), 讀數(shù)據(jù)的功能, 從機的代碼因為展示不需要,沒寫. 園子里面有個兄弟寫了iic的代碼.但是里面有點毒,多發(fā)了次地址驗證,所以才有這篇文章; 代碼注釋比較多, 愿君少走彎路? 以下是頭文件主要

    2024年02月03日
    瀏覽(43)
  • CH573-08-BLE藍牙(通信與點燈)——RISC-V內(nèi)核BLE MCU快速開發(fā)教程

    CH573-08-BLE藍牙(通信與點燈)——RISC-V內(nèi)核BLE MCU快速開發(fā)教程

    ???ch573芯片集成低功耗 2.4-GHz 無線通訊模塊,包括 RF 收發(fā)器、基帶和鏈路控制以及天線匹配網(wǎng)絡,支持低功耗藍牙 BLE。內(nèi)部提供一百多個寄存器用于調(diào)節(jié)參數(shù)和控制過程及狀態(tài),官方優(yōu)化的通訊協(xié)議棧和應用層 API,支持組網(wǎng),支持各種主流操作系統(tǒng)下的上位機開發(fā),提

    2024年02月09日
    瀏覽(28)
  • ESP32開發(fā)環(huán)境搭建Windows VSCode集成Espressif IDF插件ESP32_IDF_V5.0開發(fā)編譯環(huán)境搭建

    ESP32開發(fā)環(huán)境搭建Windows VSCode集成Espressif IDF插件ESP32_IDF_V5.0開發(fā)編譯環(huán)境搭建

    下載網(wǎng)址:https://dl.espressif.com/dl/esp-idf/ 打開上面的網(wǎng)頁,選擇單擊頁面中 ESP32-IDF v5.0.2 - Offine Installer,5.0.2是當前最新版本,如果沒有ESP32-IDF v5.0.2 - Offine Installer,說明官方有更新最新版本,如果想要安裝此教程版本可以把頁面翻到最下面,會列出所有歷史版本供用戶下載。

    2024年02月13日
    瀏覽(23)
  • ESP32開發(fā):1、環(huán)境搭建(基于vscode+ESP-IDF)

    ESP32開發(fā):1、環(huán)境搭建(基于vscode+ESP-IDF)

    ESP-IDF提供操作ESP32芯片的API函數(shù),供用戶編寫的用戶程序調(diào)用。當用戶程序編寫好后,ESP-IDF需要借助一系列編譯工具才能將用戶程序+API函數(shù)編譯成能運行在ESP32上的二進制文件。 如上圖所示這個1個G左右大的壓縮包就是ESP-IDF。如果電腦上已經(jīng)存在了這個文件,就可以不用下

    2024年02月12日
    瀏覽(26)
  • ESP-IDF開發(fā)框架添加自定義組件 ESP32-C3

    因為熟悉了STM32的開發(fā)方式,同時隨著項目文件越來越多,可以將自己寫的代碼分模塊添加到工程中,下面分析如何將自己寫的組件添加到工程中使其能夠正常編譯運行。 在ESP-IDF中,構(gòu)建,編譯,以及下載都是通過idf.py腳本來實現(xiàn)的,該腳本使用 CMake,配置待構(gòu)建的項目 N

    2024年02月02日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包