ESP32 基础2

边缘 AI 方案介绍 - - — ESP-Techpedia latest 文档

ESP-IoT-Solution 编程指南 - - — ESP-IoT-Solution latest 文档

ESP-IoT-Solution 编程指南 - - — ESP-IoT-Solution latest 文档

 

ESP-DL(DEEP LEARINIG)

入门指南 - - — ESP-DL 用户指南 latest 文档

git clone https://gitee.com/esp-components/esp-dl

//

一键安装依赖库 pip install -r requirests.txt

// 量化工具 ppq 
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
pip install esp-ppq
pip install Numba
pip install ONNX
pip install ONNX Runtime
pip install ONNX Optimizer

一锓转模型

//

一键加载 

//

安装 使用 

 

 

 

https://blog.csdn.net/espressif/article/details/128248431

https://cn.bing.com/fd/ls/GLinkPing.aspx?IG=9CFE88BA3E9D4DF99AB90B1AFCED7A50&&ID=SERP,5195.2&SUIH=mTA0mfi4jqx4XLYi3kEqBg&redir=aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2VzcHJlc3NpZi9hcnRpY2xlL2RldGFpbHMvMTI4MjQ4NDMx

人脸识别

https://gitee.com/EspressifSystems/esp-who

//

 

 语音识别(asr -tts ) 

sr-skaint (示例 examples components ,include test MULTINET_module ,documents

https://gitee.com/xv-shuai/esp-skainet

https://gitee.com/xv-shuai/esp-skainet

入门指南 - ESP32-S3 - — ESP-SR latest 文档

安可信

A1S

 

JSON

json(直接搜 idf cjson) components 目录下

事件循环库 

事件循环库 - ESP32 - — ESP-IDF 编程指南 v5.5 文档(什么时候用,什么时候不用,效率,快速,多任务)

//



// 1. 定义事件处理程序
void run_on_event(void* handler_arg, esp_event_base_t base, int32_t id, void* event_data)
{
    // 事件处理程序逻辑
}

void app_main()
{
    // 2. 用一个类型为 esp_event_loop_args_t 的配置结构体,指定所创建循环的属性。获取一个类型为 esp_event_loop_handle_t 的句柄,用于其他 API 引用循环、执行操作。
    esp_event_loop_args_t loop_args = {
        .queue_size = ...,
        .task_name = ...
        .task_priority = ...,
        .task_stack_size = ...,
        .task_core_id = ...
    };

    esp_event_loop_handle_t loop_handle;

    esp_event_loop_create(&loop_args, &loop_handle);

    // 3. 注册在 (1) 中定义的事件处理程序。MY_EVENT_BASE 和 MY_EVENT_ID 指定了一个假设事件:将处理程序 run_on_event 发布到循环中时,执行该处理程序。
    esp_event_handler_register_with(loop_handle, MY_EVENT_BASE, MY_EVENT_ID, run_on_event, ...);

    ...

    // 4. 将事件发布到循环中。此时,事件排入事件循环队列,在某个时刻,事件循环会执行已注册到发布事件的事件处理程序,例如此处的 run_on_event。为简化过程,此示例从 app_main 调用 esp_event_post_to,实际应用中可从任何其他任务中发布事件。
    esp_event_post_to(loop_handle, MY_EVENT_BASE, MY_EVENT_ID, ...);

    ...

    // 5. 注销无用的处理程序。
    esp_event_handler_unregister_with(loop_handle, MY_EVENT_BASE, MY_EVENT_ID, run_on_event);

    ...

    // 6. 删除无用的事件循环。
    esp_event_loop_delete(loop_handle);
}







esp-idf: ESP-IDF 是由乐鑫官方推出的针对 ESP32 和 ESP32-S2 系列芯片的开发框架。ESP-IDF 国内镜像仓库,Issues 和 PRs 请仍旧提交到 github。重要:Gitee 中 ESP-IDF 仓库的使用,请先参看 https://gitee.com/EspressifSystems/esp-gitee-tools 中的说明文档。ESP-IDF 及其子模块,每日会自动同步若干次。 - Gitee.com

//esp-adf\examples\ai_agent\volc_rtc\main\coze_http_request.c
coze_http_req_result_t *result = (coze_http_req_result_t *)impl_malloc_fn(sizeof(coze_http_req_result_t));
    cJSON *root = cJSON_Parse(rsp_string);
    if (root == NULL) {
        ESP_LOGW(TAG, "Error parsing JSON\n");
        return NULL;
    }

    cJSON *data = cJSON_GetObjectItem(root, "data");
    if (data != NULL) {
        cJSON *token = cJSON_GetObjectItem(data, "token");
        if (token != NULL && cJSON_IsString(token)) {
            ESP_LOGD(TAG, "Token: %s\n", token->valuestring);
            result->token = impl_strdup_fn(token->valuestring);
            HTTP_REQ_MEM_CHECK( result->token, goto _exit);
        }

        cJSON *uid = cJSON_GetObjectItem(data, "uid");
        if (uid != NULL && cJSON_IsString(uid)) {
            ESP_LOGD(TAG, "UID: %s\n", uid->valuestring);
            result->uid = impl_strdup_fn(uid->valuestring);
            HTTP_REQ_MEM_CHECK( result->uid, goto _exit);
        }

        cJSON *room_id = cJSON_GetObjectItem(data, "room_id");
        if (room_id != NULL && cJSON_IsString(room_id)) {
            ESP_LOGD(TAG, "Room ID: %s\n", room_id->valuestring);
            result->room_id = impl_strdup_fn(room_id->valuestring);
            HTTP_REQ_MEM_CHECK( result->uid, goto _exit);
        }

        cJSON *app_id = cJSON_GetObjectItem(data, "app_id");
        if (app_id != NULL && cJSON_IsString(app_id)) {
            ESP_LOGD(TAG, "App ID: %s\n", app_id->valuestring);
            result->app_id = impl_strdup_fn(app_id->valuestring);
            HTTP_REQ_MEM_CHECK(result->app_id, goto _exit);
        }
    }

    cJSON *code = cJSON_GetObjectItem(root, "code");
    if (code != NULL && cJSON_IsNumber(code)) {
        ESP_LOGD(TAG, "Code: %d\n", code->valueint);
    } else {
        ESP_LOGE(TAG, "Code not found in response");
        goto _exit;
    }

    cJSON_Delete(root);
    return result;

_exit:
    coze_http_request_free(result);
    cJSON_Delete(root);
    return NULL;
First up, how do I build?
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
For example, to build the test app:

gcc cJSON.c test.c -o test -lm
./test


As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
in one of two modes: Auto and Manual. Let's have a quick run-through.


I lifted some JSON from this page: http://www.json.org/fatfree.html
That page inspired me to write cJSON, which is a parser that tries to share the same
philosophy as JSON itself. Simple, dumb, out of the way.

Some JSON:
{
    "name": "Jack (\"Bee\") Nimble",
    "format": {
        "type":       "rect",
        "width":      1920,
        "height":     1080,
        "interlace":  false,
        "frame rate": 24
    }
}

Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
you have a char * to it. Everything is a cJSON struct.
Get it parsed:
	cJSON *root = cJSON_Parse(my_json_string);

This is an object. We're in C. We don't have objects. But we do have structs.
What's the framerate?

	cJSON *format = cJSON_GetObjectItem(root,"format");
	int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;


Want to change the framerate?
	cJSON_GetObjectItem(format,"frame rate")->valueint=25;

Back to disk?
	char *rendered=cJSON_Print(root);

Finished? Delete the root (this takes care of everything else).
	cJSON_Delete(root);

That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
before you dereference them. If you want to see how you'd build this struct in code?
	cJSON *root,*fmt;
	root=cJSON_CreateObject();
	cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
	cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
	cJSON_AddStringToObject(fmt,"type",		"rect");
	cJSON_AddNumberToObject(fmt,"width",		1920);
	cJSON_AddNumberToObject(fmt,"height",		1080);
	cJSON_AddFalseToObject (fmt,"interlace");
	cJSON_AddNumberToObject(fmt,"frame rate",	24);

Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
a few from elsewhere.

What about manual mode? First up you need some detail.
Let's cover how the cJSON objects represent the JSON data.
cJSON doesn't distinguish arrays from objects in handling; just type.
Each cJSON has, potentially, a child, siblings, value, a name.

The root object has: Object Type and a Child
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
Sibling has type Object, name "format", and a child.
That child has type String, name "type", value "rect", and a sibling:
Sibling has type Number, name "width", value 1920, and a sibling:
Sibling has type Number, name "height", value 1080, and a sibling:
Sibling has type False, name "interlace", and a sibling:
Sibling has type Number, name "frame rate", value 24

Here's the structure:
typedef struct cJSON {
	struct cJSON *next,*prev;
	struct cJSON *child;

	int type;

	char *valuestring;
	int valueint;
	double valuedouble;

	char *string;
} cJSON;

By default all values are 0 unless set by virtue of being meaningful.

next/prev is a doubly linked list of siblings. next takes you to your sibling,
prev takes you back from your sibling to you.
Only objects and arrays have a "child", and it's the head of the doubly linked list.
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
cJSON.h

A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
valuedouble.

Any entry which is in the linked list which is the child of an object will have a "string"
which is the "name" of the entry. When I said "name" in the above example, that's "string".
"string" is the JSON name for the 'variable name' if you will.

Now you can trivially walk the lists, recursively, and parse as you please.
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
the root object, and traverse the structure (which is, formally, an N-tree),
and tokenise as you please. If you wanted to build a callback style parser, this is how
you'd do it (just an example, since these things are very specific):

void parse_and_callback(cJSON *item,const char *prefix)
{
	while (item)
	{
		char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
		sprintf(newprefix,"%s/%s",prefix,item->name);
		int dorecurse=callback(newprefix, item->type, item);
		if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
		item=item->next;
		free(newprefix);
	}
}

The prefix process will build you a separated list, to simplify your callback handling.
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
let you invoke it per-item. For the item above, your callback might look like this:

int callback(const char *name,int type,cJSON *item)
{
	if (!strcmp(name,"name"))	{ /* populate name */ }
	else if (!strcmp(name,"format/type")	{ /* handle "rect" */ }
	else if (!strcmp(name,"format/width")	{ /* 800 */ }
	else if (!strcmp(name,"format/height")	{ /* 600 */ }
	else if (!strcmp(name,"format/interlace")	{ /* false */ }
	else if (!strcmp(name,"format/frame rate")	{ /* 24 */ }
	return 1;
}

Alternatively, you might like to parse iteratively.
You'd use:

void parse_object(cJSON *item)
{
	int i; for (i=0;i<cJSON_GetArraySize(item);i++)
	{
		cJSON *subitem=cJSON_GetArrayItem(item,i);
		// handle subitem.
	}
}

Or, for PROPER manual mode:

void parse_object(cJSON *item)
{
	cJSON *subitem=item->child;
	while (subitem)
	{
		// handle subitem
		if (subitem->child) parse_object(subitem->child);

		subitem=subitem->next;
	}
}

Of course, this should look familiar, since this is just a stripped-down version
of the callback-parser.

 

freertos

FreeRTOS 常用 API - - — ESP-Techpedia latest 文档

//
int i = 0;
static void task(void *arg)
{
    while(1){
        printf("%d",i);
        i++;
    }
}

void app_main(void)
{
    xTaskCreate(task,"task",2048,NULL,5,NULL);  //fun,name,stack,arg,prio,handle 函数,名,堆大小,参数,级别,句柄

}

         xtaskcreate(fun,"name",2048,arg,5,handle)

消息队列

消息队列

QueueHandle_t gpio_queue = NULL;

gpio_queue = xQueueCreate(10,sizeof(uint32_t));

        isr:

        xQueueSendFromISR(gpio_queue,&gpio_num,NULL);

        xQueueReceive(gpio_queue,&io_num,1000);

   

 

WIFI 

 

socket 

wifi example

#include <stdint.h>
#include "esp_log.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "esp_wifi.h"
#include "nvs_flash.h"

void app_main(){
    nvs_flash_init(); //存储断网重连数据 
    esp_netif_init();
    esp_event_loop_create_default();
    example_connect();

    wifi_ap_record_t ap_info;
    esp_wifi_sta_get_ap_info(&ap_info);

    //print information
    ESP_LOG_BUFFER_HEX("MAC Address",ap_info.bssid,sizeof(ap_info.bssid));
    ESP_LOG_BUFFER_CHAR("SSID",ap_info.ssid,sizeof(ap_info.ssid));
    ESP_LOGI("WIFI","Primary Channel:%d",ap_info.primary);
    ESP_LOGI("WIFI","RSSI:%d",ap_info.rssi);



    ESP_ERROR_CHECK(example_disconnect());

  
}

//idf.py create-manifest
//dependencies:
//  protocol_examples_common:
//    path: ${IDF_PATH}/examples/common_components/protocol_examples_common

wifi http

 

 

 

HFP事件

GAP 回调事件 

enumerator ESP_BT_GAP_DISC_RES_EVT
Device discovery result event 设备发现结果事件

enumerator ESP_BT_GAP_DISC_STATE_CHANGED_EVT
Discovery state changed event 发现状态更改事件

enumerator ESP_BT_GAP_RMT_SRVCS_EVT
Get remote services event 获取远程服务事件

enumerator ESP_BT_GAP_RMT_SRVC_REC_EVT
Get remote service record event 获取远程服务记录

enumerator ESP_BT_GAP_AUTH_CMPL_EVT
Authentication complete event 认证完成

enumerator ESP_BT_GAP_PIN_REQ_EVT
Legacy Pairing Pin code request 传统配对密码请示

enumerator ESP_BT_GAP_CFM_REQ_EVT
Security Simple Pairing User Confirmation request. 安全简单配对用户确认

enumerator ESP_BT_GAP_KEY_NOTIF_EVT
Security Simple Pairing Passkey Notification 安全简单配对密码通知

enumerator ESP_BT_GAP_KEY_REQ_EVT
Security Simple Pairing Passkey request 安全简单配对密码请求

enumerator ESP_BT_GAP_READ_RSSI_DELTA_EVT
Read rssi event 阅读rssi事件

enumerator ESP_BT_GAP_CONFIG_EIR_DATA_EVT
Config EIR data event 配置eir数据事件

enumerator ESP_BT_GAP_SET_AFH_CHANNELS_EVT
Set AFH channels event 设置AFH频道事件

enumerator ESP_BT_GAP_READ_REMOTE_NAME_EVT
Read Remote Name event 读取过程名称事件

enumerator ESP_BT_GAP_MODE_CHG_EVT
enumerator ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT
remove bond device complete event  移除设备完成

enumerator ESP_BT_GAP_QOS_CMPL_EVT
QOS complete event QOS完成事件

enumerator ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT
ACL connection complete status event ACL连接完成状态事件

enumerator ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVTACL断开连接完成事件
ACL disconnection complete status event

enumerator ESP_BT_GAP_SET_PAGE_TO_EVT设置页面超时事件
Set page timeout event

enumerator ESP_BT_GAP_GET_PAGE_TO_EVT获取页面超时事件
Get page timeout event

enumerator ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT 设置ACL数据包类型事件
Set ACL packet types event

enumerator ESP_BT_GAP_ENC_CHG_EVT加密更改事件
Encryption change event

enumerator ESP_BT_GAP_SET_MIN_ENC_KEY_SIZE_EVT 设置最低加密密钥
Set minimum encryption key size

enumerator ESP_BT_GAP_GET_DEV_NAME_CMPL_EVT获取设备完整名称事件
Get device name complete event

enumerator ESP_BT_GAP_EVT_MAX 查询模式 一般查询模式 有限查询模式


//-------------------------------------------------------------------

HFP 回调事件
enumerator ESP_HF_CLIENT_CONNECTION_STATE_EVT
连接状态改变事件

enumerator ESP_HF_CLIENT_AUDIO_STATE_EVT
音频连接状态变化事件

enumerator ESP_HF_CLIENT_BVRA_EVT
语音识别状态变更事件

enumerator ESP_HF_CLIENT_CIND_CALL_EVT
呼叫指示

enumerator ESP_HF_CLIENT_CIND_CALL_SETUP_EVT
呼叫建立指示

enumerator ESP_HF_CLIENT_CIND_CALL_HELD_EVT
呼叫被占指示

enumerator ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT
网络服务可用性指示

enumerator ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT
信号强度指示

enumerator ESP_HF_CLIENT_CIND_CALL_SETUP_EVT
呼叫建立指示

enumerator ESP_HF_CLIENT_CIND_CALL_HELD_EVT
呼叫被占指示

enumerator ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT
网络服务可用性指示

enumerator ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT
信号强度指示

enumerator ESP_HF_CLIENT_CIND_ROAMING_STATUS_EVT
漫游状态指示

enumerator ESP_HF_CLIENT_CIND_BATTERY_LEVEL_EVT
电量指示

enumerator ESP_HF_CLIENT_COPS_CURRENT_OPERATOR_EVT
当前运营商信息

enumerator ESP_HF_CLIENT_BTRH_EVT
呼叫响应与保留事件

enumerator ESP_HF_CLIENT_CLIP_EVT
呼叫线路识别通知 

enumerator ESP_HF_CLIENT_CCWA_EVT
呼叫等待通知

enumerator ESP_HF_CLIENT_CLCC_EVT
当前呼叫通知列表

enumerator ESP_HF_CLIENT_VOLUME_CONTROL_EVT
来自AG的音频音量控制命令, provided by +VGM or +VGS message

enumerator ESP_HF_CLIENT_AT_RESPONSE_EVT
AT命令响应事件

enumerator ESP_HF_CLIENT_CNUM_EVT
来自AG的用户信息回复 

enumerator ESP_HF_CLIENT_BSIR_EVT
带内铃声的设置

enumerator ESP_HF_CLIENT_BINP_EVT
AG要求的最后一个语音标签量
requested number of last voice tag from AG

enumerator ESP_HF_CLIENT_RING_IND_EVT
ring indication event

enumerator ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT请求数据包数量差异
requested number of packet different status

enumerator ESP_HF_CLIENT_PROF_STATE_EVT指示HF CLIENT 初始化或结束完成
Indicate HF CLIENT init or deinit complete

bluedroid

esp_bluedroid_status_t esp_bluedroid_get_status(void) 获取蓝牙堆栈状态。
esp_err_t esp_bluedroid_enable(void) 启用蓝牙,必须在esp_bluedroid_init()/esp_bluedroid_init_with_cfg()之后
esp_err_t esp_bluedroid_disable(void) 禁用蓝牙,必须在esp_bluedroid_deinit()之前调用
esp_err_t esp_bluedroid_init(void) 初始化并分配蓝牙资源,必须在任何蓝牙操作之前。
esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) 初始化并分配蓝牙资源,必须在任何蓝牙操作之前。
esp_err_t esp_bluedroid_deinit(void)  解除蓝牙资源的初始化并释放资源,必须在每次使用蓝牙之后进行

device
esp_err_t esp_bt_config_file_path_update 此函数用于更新保存在NVS模块中的蓝牙绑定键的路径名,需要在esp_bluedroid_init()之前调用。
esp_err_t esp_bt_config_file_path_get 该函数用于获取保存在NVS模块中的蓝牙绑定密钥的路径名。
esp_err_t esp_bt_dev_coex_status_config 配置蓝牙设备共存状态。此函数应在esp_bluedroid_enable()成功完成后调用。
esp_err_t esp_bt_dev_get_device_nam 获取蓝牙设备名称。此函数应在esp_bluedroid_enable()成功完成后调用。
esp_err_t esp_bt_dev_set_device_name 设置蓝牙设备名称。此函数应在esp_bluedroid_enable()成功完成后调用。
const uint8_t *esp_bt_dev_get_address 获取蓝牙设备地址。必须在“esp_bluedroid_enable”之后使用。
esp_err_t esp_bt_dev_register_callback  注册回调函数。此函数应在esp_bluedroid_enable()成功完成后调用


contrl &HCI

esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)  //初始化蓝牙控制器以分配任务和其他资源。
esp_err_t esp_bt_controller_deinit(void)  //解除蓝牙控制器的初始化,以释放资源并删除任务。
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)  //启用蓝牙控制器
esp_err_t esp_bt_controller_disable(void)  //禁用蓝牙控制器
esp_bt_controller_status_t esp_bt_controller_get_status(void)  //获取状态
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)  //释放空间用于BT或BLE (内存不足时)
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)  //根据模式释放控制器内存、BSS和经典蓝牙/BLE主机堆栈的数据部分。
esp_err_t esp_bt_sleep_enable(void)  //睡眠功能
esp_err_t esp_bt_sleep_disable(void)  //关闭睡眠 
esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level) 设置BLE传输功率。
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type)  获取蓝牙传输功率。
esp_err_t esp_ble_scan_duplicate_list_flush(void) 手动清除蓝牙扫描重复列表。
esp_err_t esp_ble_scan_dupilcate_list_flush(void)
esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level) 设置BR/EDR传输功率。
esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level)
esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)
bool esp_vhci_host_check_send_available(void)
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void)
esp_err_t esp_bt_set_lpclk_src(esp_bt_sleep_clock_t lpclk)

高级功能:

 

蓝牙 

 

bta btc bdm(device manage) 

 

ESP Friends - - — ESP-Techpedia latest 文档

mesh zigbee now 区别 

不同 Mesh 方案的对比 - - — ESP-Techpedia latest 文档

Mesh Solution Comparison

Feature

ESP BLE Mesh

ESP Thread Mesh

ESP-Mesh-Lite

ZigBee Mesh

ESP-Now

节点数量

理论不大于 32767 个,内部测试可达 100 个节点

内部测试可达 300 个节点

内部测试可达 100 个节点

理论上限 65000 个,内部测试可达 300 个节点

小于 100 个节点

节点间通信距离

视发包功率而定,推荐相邻节点距离不大于 50 m

维持连接的距离可达 200 m

小于 100 m,经测试可达 170 m

维持连接的距离可达 300 m

推荐不大于 150 m

吞吐量

低,小于 1 Kbps

低,实际测试约为 4 - 5 KB/s

高,实际测试最高为 20 Mbps,层级越深吞吐越低

低,实际测试约为 16.9 Kbps

低,小于 0.5 Mbps

单跳延时

50 m 极限距离时为 100 ms 以内,正常距离(低于 50 m 时)为 50 ms 以内

平均 10 ms

100 ms 以内

平均 16 ms

10 ms 以内

乐鑫各类 Mesh 方案核心参数说明如下。

 

组网:

now 

 

airkiss 

 

mesh 

 

 

蓝牙

ad2p 

//

hfp 

//

 

摄像头(官网源码)

/*
 * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_panel_ops.h"
#include "esp_ldo_regulator.h"
#include "esp_cache.h"
#include "driver/i2c_master.h"
#include "driver/isp.h"
#include "esp_cam_ctlr_isp_dvp.h"
#include "esp_cam_ctlr.h"
#include "example_dsi_init.h"
#include "example_dsi_init_config.h"
#include "example_sensor_init.h"
#include "example_config.h"
#include "driver/ledc.h"

static const char *TAG = "dvp_isp_dsi";

static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data);
static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data);

// Generate a 20MHz clock for DVP XCLK
static void s_ledc_generate_dvp_xclk(void)
{
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_LOW_SPEED_MODE,
        .duty_resolution  = LEDC_TIMER_1_BIT,
        .timer_num        = LEDC_TIMER_0,
        .freq_hz          = EXAMPLE_ISP_DVP_CAM_XCLK_FREQ_HZ,  // Set output frequency at 20 MHz
        .clk_cfg          = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_channel = {
        .speed_mode     = LEDC_LOW_SPEED_MODE,
        .channel        = LEDC_CHANNEL_0,
        .timer_sel      = LEDC_TIMER_0,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = EXAMPLE_ISP_DVP_CAM_XCLK_IO,
        .duty           = 1, // Set duty to 50%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}

void app_main(void)
{
    esp_err_t ret = ESP_FAIL;
    esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
    esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
    esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
    void *frame_buffer = NULL;
    size_t frame_buffer_size = 0;

    //mipi ldo
    esp_ldo_channel_handle_t ldo_mipi_phy = NULL;
    esp_ldo_channel_config_t ldo_mipi_phy_config = {
        .chan_id = CONFIG_EXAMPLE_USED_LDO_CHAN_ID,
        .voltage_mv = CONFIG_EXAMPLE_USED_LDO_VOLTAGE_MV,
    };
    ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy));

    /**
     * @background
     * Sensor use RAW8
     * ISP convert to RGB565
     */
    //---------------DSI Init------------------//
    example_dsi_resource_alloc(&mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer);

    //---------------Necessary variable config------------------//
    frame_buffer_size = CONFIG_EXAMPLE_CAM_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;

    ESP_LOGD(TAG, "CONFIG_EXAMPLE_CAM_HRES: %d, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES: %d, bits per pixel: %d", CONFIG_EXAMPLE_CAM_HRES, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES, EXAMPLE_RGB565_BITS_PER_PIXEL);
    ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size);
    ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer);

    esp_cam_ctlr_trans_t cam_trans = {
        .buffer = frame_buffer,
        .buflen = frame_buffer_size,
    };

    //--------Camera Sensor and SCCB Init-----------//
    s_ledc_generate_dvp_xclk();

    example_sensor_config_t cam_sensor_config = {
        .i2c_port_num = I2C_NUM_0,
        .i2c_sda_io_num = EXAMPLE_ISP_DVP_CAM_SCCB_SDA_IO,
        .i2c_scl_io_num = EXAMPLE_ISP_DVP_CAM_SCCB_SCL_IO,
        .port = ESP_CAM_SENSOR_DVP,
        .format_name = EXAMPLE_CAM_FORMAT,
    };
    i2c_master_bus_handle_t i2c_bus_handle = NULL;
    example_sensor_init(&cam_sensor_config, &i2c_bus_handle);

    //---------------ISP Init------------------//
    isp_proc_handle_t isp_proc = NULL;
    esp_isp_processor_cfg_t isp_config = {
        .clk_hz = 80 * 1000 * 1000,
        .input_data_source = ISP_INPUT_DATA_SOURCE_DVP,
        .input_data_color_type = ISP_COLOR_RAW8,
        .output_data_color_type = ISP_COLOR_RGB565,
        .has_line_start_packet = false,
        .has_line_end_packet = false,
        .h_res = CONFIG_EXAMPLE_CAM_HRES,
        .v_res = CONFIG_EXAMPLE_CAM_VRES,
    };
    ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));
    ESP_ERROR_CHECK(esp_isp_enable(isp_proc));

    //----------CAM Controller Init------------//
    esp_cam_ctlr_handle_t cam_handle = NULL;
    esp_cam_ctlr_isp_dvp_cfg_t dvp_config = {
        .data_width = EXAMPLE_ISP_DVP_CAM_DATA_WIDTH,
        .data_io = {
            EXAMPLE_ISP_DVP_CAM_D0_IO,
            EXAMPLE_ISP_DVP_CAM_D1_IO,
            EXAMPLE_ISP_DVP_CAM_D2_IO,
            EXAMPLE_ISP_DVP_CAM_D3_IO,
            EXAMPLE_ISP_DVP_CAM_D4_IO,
            EXAMPLE_ISP_DVP_CAM_D5_IO,
            EXAMPLE_ISP_DVP_CAM_D6_IO,
            EXAMPLE_ISP_DVP_CAM_D7_IO,
        },
        .pclk_io = EXAMPLE_ISP_DVP_CAM_PCLK_IO,
        .hsync_io = EXAMPLE_ISP_DVP_CAM_HSYNC_IO,
        .vsync_io = EXAMPLE_ISP_DVP_CAM_VSYNC_IO,
        .de_io = EXAMPLE_ISP_DVP_CAM_DE_IO,
        .io_flags.vsync_invert = 1,
        .queue_items = 10,
    };
    ret = esp_cam_new_isp_dvp_ctlr(isp_proc, &dvp_config, &cam_handle);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "isp dvp init fail[%d]", ret);
        return;
    }

    esp_cam_ctlr_evt_cbs_t cbs = {
        .on_get_new_trans = s_camera_get_new_vb,
        .on_trans_finished = s_camera_get_finished_trans,
    };
    if (esp_cam_ctlr_register_event_callbacks(cam_handle, &cbs, &cam_trans) != ESP_OK) {
        ESP_LOGE(TAG, "ops register fail");
        return;
    }

    ESP_ERROR_CHECK(esp_cam_ctlr_enable(cam_handle));

    //---------------DPI Reset------------------//
    example_dpi_panel_reset(mipi_dpi_panel);

    //init to all white
    memset(frame_buffer, 0xFF, frame_buffer_size);
    esp_cache_msync((void *)frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);

    example_dpi_panel_init(mipi_dpi_panel);

    if (esp_cam_ctlr_start(cam_handle) != ESP_OK) {
        ESP_LOGE(TAG, "Driver start fail");
        return;
    }

    while (1) {
        ESP_ERROR_CHECK(esp_cam_ctlr_receive(cam_handle, &cam_trans, ESP_CAM_CTLR_MAX_DELAY));
    }
}

static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)
{
    esp_cam_ctlr_trans_t cam_trans = *(esp_cam_ctlr_trans_t *)user_data;
    trans->buffer = cam_trans.buffer;
    trans->buflen = cam_trans.buflen;

    return false;
}

static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)
{
    return false;
}


 

飞控

//

低功耗 关闭蓝牙 WIFI

//

深度睡眠

 

 

mp4 jpg 

avi esp friends 

sd卡 存储 sdmcc spi 区别 速度 线数 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值