【zigbee】ESP32-C6 + Home Assistant Connect ZBT-1 接入 Home Assistant,实现上传温度和控制灯光

目录

前言

一、项目背景与硬件准备

1.1 为什么选这套方案?

1.2 硬件清单

二、Home Assistant 环境搭建

2.1 VMware 虚拟机安装 HAOS

2.2 Home Assistant Connect ZBT-1 配置

三、ESP32-C6 代码实现

3.1 配置

3.2 核心代码

3.3 构建运行

四、调试结果

结语

程序源码


前言

在物联网与智能家居开发中,基于 Zigbee 协议实现设备间的低功耗、自组网通信,并接入开放平台进行统一管控,是极具代表性的实战场景。

本文以 ESP32-C6 为核心硬件,基于 ESP-IDF 开发环境,从零开始手把手带你在 Linux 系统下配置 Home Assistant 智能家居平台、开发 Zigbee 终端设备代码,并成功接入。全文贯穿实战,附完整代码与避坑指南,助你快速上手。

一、项目背景与硬件准备

1.1 为什么选这套方案?

组件选择理由
ESP32-C6原生支持 Zigbee 3.0 / Thread / Matter,性价比高
Home Assistant Connect ZBT-1官方 Zigbee 协调器,开箱即用,支持 ZHA 和 Zigbee2MQTT
Home Assistant OS (虚拟机)功能完整,支持插件商店,方便扩展

1.2 硬件清单

  • ESP32-C6 开发板

  • Home Assistant Connect ZBT-1 协调器(含 USB 延长线)

  • 运行 Home Assistant 的主机(本文使用 VMware 虚拟机,操作系统为 Ubuntu)

  • USB 数据线(用于烧录 ESP32-C6)

注意:ZBT-1 建议使用 USB 延长线,USB 3.0 接口会对 2.4GHz Zigbee 信号产生严重干扰。

二、Home Assistant 环境搭建

2.1 VMware 虚拟机安装 HAOS

从 Home Assistant 官网下载 VMware 专用镜像(.vmdk 格式)

Windows - Home Assistant

本项目以 Windows 安装 VMware 虚拟机为例,基于 Ubuntu 操作系统,需要改动配置如下:

1、 磁盘文件地址改成 Home Assistant 镜像文件地址

如果你是创建虚拟机时设置的,可以直接改;如果你是原有虚拟机改装过来的,磁盘文件地址改不了,可以将 Home Assistant 镜像文件复制到原有磁盘文件地址(如:L:\ubuntu),然后删除原有磁盘文件,将 Home Assistant 镜像文件重命名为原有磁盘文件(如:Ubuntu_64-000001)

2、 网络适配器改成为桥接模式

3、 USB 改成 3.0 及以上

4、 修改 .vmx 配置文件

添加 firmware = "efi" 启用 UEFI 引导

做完这些,就可以启动虚拟机,等待配置,如果出现以下界面,则操作成功:

访问 http://homeassistant.local:8123 ,一开始需要注册,注册完就是类似如下界面:

2.2 Home Assistant Connect ZBT-1 配置

将 ZBT-1 插入电脑(要选择连接虚拟机,而不是主机),Home Assistant 一般会自动发现。如果是以下显示就是连接成功:

在 Home Assistant 界面,点击设置 → 设备与服务:

点击发现的 ZBT-1,选择 “用作 Zigbee 适配器”,选择 “推荐安装”(使用 ZHA 集成),按提示将适配器分配到某个区域(如“客厅”),然后点击完成(finish),Zigbee 网络就创建好了。

注意:如果自动发现失败,可以检查 VMware 的 USB 直通设置,确保 ZBT-1 已连接到虚拟机。

三、ESP32-C6 代码实现

3.1 配置

在写代码之前需要确定 zigbee 的 sdk 配置,看看你 ESP32-IDF 的文件里有没有 esp-zigbee-sdk 。

如果没有,克隆 esp-zigbee-sdk :

在 cmd 中,进入 ESP-IDF 的目录(如:Q:\ESP32\IDF\Espressif):

cd Q:\ESP32\IDF\Espressif

然后克隆:

git clone https://github.com/espressif/esp-zigbee-sdk.git

3.2 核心代码

 在 ESP32-IDF 的 SDK配置编辑器中,修改配置如下:

主文件夹的 CMakeLists.txt

# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/../../esp-zigbee-sdk/components)

list(PREPEND SDKCONFIG_DEFAULTS "sdkconfig.defaults")

set(EXCLUDE_COMPONENTS esp-zigbee-console)   # 排除不兼容的组件

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(7_zigbee)

main 文件夹的 CMakeLists.txt

idf_component_register(SRC_DIRS "."
                       PRIV_INCLUDE_DIRS "."
                       PRIV_REQUIRES vfs nvs_flash BSP Middlewares)

idf_component.yml

## IDF Component Manager Manifest File
dependencies:
  ## Required IDF version
  idf:
    version: ">=5.2"
  espressif/esp-zigbee-lib:
    version: ">=2.0.0"

main.c

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stdio.h>
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_zigbee.h"
#include "ezbee/zha.h"               // EZBee ZHA 设备创建 API
#include "driver/gpio.h"

#include "led.h"
#include "myadc.h"
#include "zigbee.h"

static const char *TAG = "MAIN";  // 日志标签

static void zigbee_task(void *pv)
{
    zigbee_init();

    // 注册信号处理器(处理栈事件)
    ESP_ERROR_CHECK(ezb_app_signal_add_handler(app_signal_handler));

    // 创建设备端点
    create_my_device();

    // 启动 Zigbee 栈(非阻塞)
    ESP_ERROR_CHECK(esp_zigbee_start(false));

    // 进入 Zigbee 主事件循环(阻塞,直到栈停止)
    esp_zigbee_launch_mainloop();

    // 正常不会执行到这里,但为了完整保留
    esp_zigbee_deinit();
    vTaskDelete(NULL);
}

// 上报温度任务
void report_task(void *pv)
{
    while (1) 
    {
        // 短地址为 0xFFFE 表示未入网
        if (ezb_nwk_get_short_address() != 0xFFFE) 
        {
            int adc_data = myadc_read();
            zigbee_report(adc_data);
        }
        else 
        {
            ESP_LOGI(TAG, "未入网, waiting...");
        }
        vTaskDelay(pdMS_TO_TICKS(15000));
    }
}

void app_main(void)
{
    // 初始化 NVS(用于 Zigbee 存储)
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(nvs_flash_init_partition("zb_storage"));

    led_init();
    myadc_init();

    // 创建 Zigbee 任务(栈大小 4096,优先级 5)
    xTaskCreate(zigbee_task, "zigbee", 4096, NULL, 5, NULL);
}

zigbee.c

#include "zigbee.h"

static const char *TAG = "MY_ZIGBEE";

void zigbee_init(void)
{
    // 配置 Zigbee 栈
    esp_zigbee_config_t config = {
        .device_config = {
            .device_type = EZB_NWK_DEVICE_TYPE_END_DEVICE,   // 终端设备
            .install_code_policy = false,
            .zed_config = {
                .ed_timeout = EZB_NWK_ED_TIMEOUT_64MIN,      // 休眠超时
                .keep_alive = 4000,
            },
        },
        .platform_config = {
            .storage_partition_name = "zb_storage",          // NVS 分区名
            .radio_config = { .radio_mode = ESP_ZIGBEE_RADIO_MODE_NATIVE },
        },
    };

    ESP_ERROR_CHECK(esp_zigbee_init(&config));

    // 启用所有 Zigbee 信道 (11-26) 进行扫描
    ezb_aps_secur_enable_distributed_security(false);
    ESP_ERROR_CHECK(ezb_bdb_set_primary_channel_set(0xFFFF));   // 所有主信道
    ESP_ERROR_CHECK(ezb_bdb_set_secondary_channel_set(0xFFFF)); // 所有备用信道
}

// 上报到 Zigbee 网络 
void zigbee_report(int adc_data)
{
    int16_t measured_value = (int16_t)adc_data;

    // 获取 Zigbee 栈锁,保护属性写入
    esp_zigbee_lock_acquire(portMAX_DELAY);

    // 设置adc_data属性
    ezb_zcl_set_attr_value(TEMP_ENDPOINT,
                           EZB_ZCL_CLUSTER_ID_TEMPERATURE_MEASUREMENT,
                           EZB_ZCL_CLUSTER_SERVER,
                           EZB_ZCL_ATTR_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_ID,
                           EZB_ZCL_STD_MANUF_CODE,          // 标准制造商码
                           (uint8_t *)&measured_value,
                           false);                           // 不发送响应
    esp_zigbee_lock_release();

    printf("Reported adc_data: %.d\r\n", adc_data);
}

// 重试入网流程
void zigbee_retry_commissioning(alarm_timer_arg_t arg)
{
    esp_zigbee_lock_acquire(portMAX_DELAY);
    ezb_bdb_start_top_level_commissioning(arg);
    esp_zigbee_lock_release();
}

// 处理栈启动、入网等事件
bool app_signal_handler(const ezb_app_signal_t *signal)
{
    ezb_app_signal_type_t type = ezb_app_signal_get_type(signal);
    switch (type) 
    {
        // 栈初始化完成,开始顶层入网流程
        case EZB_ZDO_SIGNAL_SKIP_STARTUP:
            ESP_LOGI(TAG, "Initialize Zigbee stack");
            ezb_bdb_start_top_level_commissioning(EZB_BDB_MODE_INITIALIZATION);
            break;
            
        // 设备首次启动或重启后的状态
        case EZB_BDB_SIGNAL_DEVICE_FIRST_START:
        case EZB_BDB_SIGNAL_DEVICE_REBOOT: {
            ezb_bdb_comm_status_t status = *(ezb_bdb_comm_status_t *)ezb_app_signal_get_params(signal);
            // 启动成功
            if (status == EZB_BDB_STATUS_SUCCESS) 
            {
                ESP_LOGI(TAG, "设备启动, %s factory-new", ezb_bdb_is_factory_new() ? "" : "not");
                // 如果是出厂新设备,则启动网络引导(入网)
                if (ezb_bdb_is_factory_new()) 
                {
                    ezb_bdb_start_top_level_commissioning(EZB_BDB_MODE_NETWORK_STEERING);
                }
                else
                {
                    ezb_bdb_start_top_level_commissioning(EZB_BDB_MODE_NETWORK_STEERING);
                }
            } 
            else 
            {
                ESP_LOGW(TAG, "设备启动失败 (0x%02x), 1秒后重试", status);
                alarm_timer_schedule(zigbee_retry_commissioning, (alarm_timer_arg_t)EZB_BDB_MODE_INITIALIZATION, 1000);
            }
            break;
        }

        // 入网结果
        case EZB_BDB_SIGNAL_STEERING: {
            ezb_bdb_comm_status_t status = *(ezb_bdb_comm_status_t *)ezb_app_signal_get_params(signal);
            if (status == EZB_BDB_STATUS_SUCCESS) 
            {
                ESP_LOGI(TAG, "Joined network! PAN ID: 0x%04x", ezb_nwk_get_panid());
                // 创建上报任务(只创建一次)
                static bool reported_created = false;
                if (!reported_created) 
                {
                    xTaskCreate(report_task, "report", 2048, NULL, 5, NULL);
                    reported_created = true;
                }
            } 
            else 
            {
                // 失败重试(使用 alarm_timer)
                ESP_LOGW(TAG, "入网失败 (0x%02x), 3秒后重试", status);
                alarm_timer_schedule(zigbee_retry_commissioning, (alarm_timer_arg_t)EZB_BDB_MODE_NETWORK_STEERING, 3000);
            }
            break;
        }

        default:
            ESP_LOGI(TAG, "Signal: %s (0x%02x)", ezb_app_signal_to_string(type), type);
            break;
    }
    return true;
}

// ZCL 核心动作回调
static void esp_zigbee_zcl_core_action_handler(ezb_zcl_core_action_callback_id_t callback_id, void *message)
{
    switch (callback_id) 
    {
        // 收到 Set Attribute 请求
        case EZB_ZCL_CORE_SET_ATTR_VALUE_CB_ID:
            // 处理 Attribute 命令
            ezb_zcl_set_attr_value_message_t *set_attr_msg = (ezb_zcl_set_attr_value_message_t *)message;
            if (!set_attr_msg) return;
            ESP_LOGI(TAG, "ZCL SetAttributeValue: endpoint=%d, cluster=0x%04x",
                    set_attr_msg->info.dst_ep, set_attr_msg->info.cluster_id);

            // 只处理 On/Off 簇的命令
            if (set_attr_msg->info.cluster_id == EZB_ZCL_CLUSTER_ID_ON_OFF) 
            {
                // 检查属性 ID 是否为 OnOff 属性(0x0000)
                if (set_attr_msg->in.attribute.id == EZB_ZCL_ATTR_ON_OFF_ON_OFF_ID) 
                {
                    uint8_t value = *(uint8_t *)set_attr_msg->in.attribute.data.value;
                    led_set(value);
                    printf("LED set to %d\r\n", value);
                }
            }
            break;

        // 收到默认响应(通常用于命令确认)
        case EZB_ZCL_CORE_DEFAULT_RSP_CB_ID: {
            ezb_zcl_cmd_default_rsp_message_t *default_rsp = (ezb_zcl_cmd_default_rsp_message_t *)message;
            ESP_LOGI(TAG, "收到默认响应 with status(0x%02x)", default_rsp->in.status_code);
            break;
        }

        default:
            ESP_LOGW(TAG, "ZCL Core Action: ID(0x%04lx)", callback_id);
            break;
    }
}

// 创建设备端点
void create_my_device(void)
{
    // 创建设备描述符
    ezb_af_device_desc_t dev_desc = ezb_af_create_device_desc();

    // 温度传感器端点(Endpoint 10)
    ezb_zha_temperature_sensor_config_t temp_cfg = EZB_ZHA_TEMPERATURE_SENSOR_CONFIG();
    // 配置测量范围:-10℃ ~ 80℃
    temp_cfg.temp_meas_cfg.min_measured_value = -1000; // -10℃
    temp_cfg.temp_meas_cfg.max_measured_value = 8000;  // 80℃
    // 温度描述符
    ezb_af_ep_desc_t temp_ep = ezb_zha_create_temperature_sensor(TEMP_ENDPOINT, &temp_cfg);
    ezb_af_device_add_endpoint_desc(dev_desc, temp_ep);

    // On/Off 灯端点(Endpoint 11)
    ezb_zha_on_off_light_config_t onoff_cfg = EZB_ZHA_ON_OFF_LIGHT_CONFIG();
    // 灯描述符
    ezb_af_ep_desc_t onoff_ep = ezb_zha_create_on_off_light(ONOFF_ENDPOINT, &onoff_cfg);
    ezb_af_device_add_endpoint_desc(dev_desc, onoff_ep);

    // 注册设备描述符到 Zigbee 栈
    ESP_ERROR_CHECK(ezb_af_device_desc_register(dev_desc));
    // 注册 ZCL 回调,用于接收命令 
    ezb_zcl_core_action_handler_register(esp_zigbee_zcl_core_action_handler);
}

zigbee.h

#ifndef ZIGBEE_H
#define ZIGBEE_H

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stdio.h>
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_zigbee.h"
#include "ezbee/zha.h"               // EZBee ZHA 设备创建 API
#include "myadc.h"
#include "led.h"
#include "alarm_timer.h"
#include "ezbee/bdb.h"

// 端点定义
#define TEMP_ENDPOINT   10            // 温度传感器端点
#define ONOFF_ENDPOINT  11            // On/Off 灯端点

extern void report_task(void *pv);

void zigbee_init(void);
void zigbee_report(int adc_data);
bool app_signal_handler(const ezb_app_signal_t *signal);
void create_my_device(void);

#endif 

alarm_timer.c

#include "alarm_timer.h"

typedef struct alarm_timer_s {
    esp_timer_handle_t     timer;
    alarm_timer_callback_t cb;
    alarm_timer_arg_t      arg;
} alarm_timer_t;

static void alarm_timer_cb(void *arg)
{
    alarm_timer_t *alarm = (alarm_timer_t *)arg;

    esp_timer_delete(alarm->timer);
    alarm->cb(alarm->arg);
    free(alarm);
}

esp_err_t alarm_timer_schedule(alarm_timer_callback_t cb, alarm_timer_arg_t arg, uint32_t time_ms)
{
    if (cb == NULL) {
        return ESP_ERR_INVALID_ARG;
    }

    alarm_timer_t *alarm = malloc(sizeof(alarm_timer_t));
    if (alarm == NULL) {
        return ESP_ERR_NO_MEM;
    }

    alarm->cb    = cb;
    alarm->arg   = arg;
    alarm->timer = NULL;

    esp_timer_create_args_t timer_args = {
        .callback = alarm_timer_cb,
        .arg      = alarm,
    };

    esp_err_t err = esp_timer_create(&timer_args, &alarm->timer);
    if (err != ESP_OK) {
        free(alarm);
        return err;
    }

    uint64_t time_us = (uint64_t)time_ms * 1000;
    err              = esp_timer_start_once(alarm->timer, time_us);
    if (err != ESP_OK) {
        esp_timer_delete(alarm->timer);
        free(alarm);
        return err;
    }

    return ESP_OK;
}

alarm_timer.h

#ifndef ALARM_TIMER_H
#define ALARM_TIMER_H

#pragma once

#include <stdlib.h>
#include "esp_timer.h"
#include <stdint.h>
#include "esp_err.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef uintptr_t alarm_timer_arg_t;

typedef void (*alarm_timer_callback_t)(alarm_timer_arg_t arg);

esp_err_t alarm_timer_schedule(alarm_timer_callback_t cb, alarm_timer_arg_t arg, uint32_t time_ms);

#ifdef __cplusplus
}
#endif

#endif // ALARM_TIMER_H

3.3 构建运行

烧录程序,在 Home Assistant 界面中,点击 Zigbee Home Automation → 添加设备,Home Assistant 会自动识别 zigbee 终端设备,完成添加。如果没有识别到,试试 ESP32c6 复位上电。

ESP32c6 调试如果是以下结果,则连接成功:

在 Zigbee Home Automation 可以看到对应的 zigbee 终端设备:

四、调试结果

温度上传 Home Assistant 界面效果:

灯光指令控制效果:

 

结语

本文通过一个完整的实战项目,展示了 ESP32-C6 如何快速接入 Home Assistant ZHA,实现 Zigbee 温度数据上报和 LED 远程控制。核心步骤包括:

  • Home Assistant 虚拟机部署:替换硬盘镜像,桥接网络等

  • ZBT-1 协调器配置:ZHA 集成,开箱即用

  • ESP32-C6 固件开发:Zigbee 终端设备 + 温度传感器 + On/Off 灯

由于水平有限,文中难免存在疏漏或不当之处,欢迎大家批评指正。如果你在尝试过程中遇到问题,欢迎留言交流、共同探讨。

程序源码

ESP32c6_zigbee

内容概要:本文围绕“基于需求侧响应的配电网供电能力综合评估”展开研究,重点探讨了价格型需求响应机制对配电网供电能力的影响,并提出了一套科学的综合评估方法。研究构建了一个涵盖一次设备安全、负荷平稳性、电能质量系统效率等多个维度的评价指标体系,采用熵权法客观确定各指标权重,并结合模糊综合评价模型实现双层评分机制,从而定量评估不同运行场景下配电网的承载能力。通过Python编程实现算法仿真,利用算例分析验证了所提模型在不同分布式能源渗透率及多种需求响应策略下的有效性与灵敏度,揭示了价格激励措施在提升电网承载力方面的积极作用,为现代配电网的规划、调度与运行优化提供了理论依据技术支撑。; 适合人群:具备一定电力系统基础知识Python编程能力,从事电力系统规划、运行优化、需求响应等相关领域的科研人员及研究生。; 使用场景及目标:①评估高比例电动汽车、分布式电源接入背景下配电网的实际供电能力;②分析价格型需求响应策略对提升电网承载力的作用效果;③为配电网扩容改造、运行调度需求管理政策制定提供决策支持; 阅读建议:建议读者结合文中提供的Python代码进行实证复现,重点关注熵权法与模糊综合评价的实现逻辑,并尝试修改参数设置以观察评估结果的变化趋势,加深对模型机理的理解。
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在Qt应用程序开发过程中,有时我们可能需要构建一个具备特殊视觉效果的窗口,例如设计成没有边框但带有阴影,并且依然允许用户拖动窗口。此类需求通常出现在构建简洁用户界面或定制化窗口外观的场景中。标题“Qt(部分)无边框窗口 边框阴影,可以拖动边框,移动窗口”所涵盖的技术要点主要集中于如何在Qt框架内达成这样的功能,尤其是借助winEvent函数的重写来应对特定的Windows平台事件。 让我们深入理解无边框窗口的概念。在Qt环境中,可以通过调整窗口的边框样式来构建无边框窗口。这通常是通过`setWindowFlags()`函数完成的,将`Qt::FramelessWindowHint`标志整合到窗口的标志参数里。例如: ```cpp setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint); ``` 这样一来,窗口将丧失标准的边框标题栏,但依然维持着窗口管理的基本功能,例如最大化、最小化关闭操作,前提是你也没有移除这些相关标志。 接下来,为了给无边框窗口增添阴影效果,可以利用Qt的QGraphicsDropShadowEffect类。首先创建一个QGraphicsView对象作为窗口的底层容器,然后在其上放置一个QGraphicsProxyWidget用以展示实际的窗口内容。接着,为QGraphicsView施加阴影效果: ```cpp QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffe...
内容概要:本文系统研究了同步电机与构网型变流器在电力系统中的频率稳定特性及其多时间尺度交互机理,基于Simulink搭建高保真仿真模型,深入分析两类电源在动态响应、惯量支撑、频率调节能力等方面的差异与耦合关系。研究涵盖不同运行工况下的频率波动响应特性,重点揭示控制延迟、电气与机械动态过程之间的时间尺度耦合机制,探讨构网型变流器在高比例新能源接入背景下对传统同步机主导系统的频率稳定性的影响,评估其替代或协同传统同步机的潜力与挑战,为未来电力系统的稳定运行与控制策略设计提供理论依据技术支撑。; 适合人群:具备电力系统分析、自动控制理论及新能源并网技术背景的科研人员、高校研究生及电力工程技术人员;熟悉Simulink仿真环境者更佳; 使用场景及目标:①深入理解同步电机与构网型变流器在频率响应特性上的本质差异及其相互作用机理;②支撑高电力电子化电网的频率稳定性分析与新型控制器设计;③为多类型电源协同控制策略的研发与仿真验证提供模型基础与分析平台; 阅读建议:建议结合Simulink仿真模型进行同步操作,重点关注不同时间尺度动态过程的建模方法与参数敏感性分析,深入探究频率稳定性的内在机理,全面把握构网型控制在提升系统稳定性方面的优势与潜在局限。
代码转载自:https://pan.quark.cn/s/db56051ee6da 依据所提供的文档资料,能够归纳出以下与“寻求一个字符串中连续出现频率最高的子串”相关的基础知识: ### 一、问题的阐述与剖析 #### 1.1 问题背景 在计算机科学领域中,字符串操作是一项普遍且关键的工作。本议题聚焦于给定字符串,识别其中连续出现频率最高的子串。 #### 1.2 问题陈述 假定存在一个输入字符串 `str`,目标在于找出该字符串中出现频率最高的一个或多个连续子串,并统计它们的出现频次。 #### 1.3 输入输出格式 - **输入**:一个字符串 `str`。 - **输出**:连续出现频率最高的子串及其对应的出现次数。 ### 二、算法的构思与执行 #### 2.1 基本理念 遍历字符串的所有可能子串,并借助某种数据结构来追踪每个子串的出现频次。通过对比所有子串的出现频次,从而识别出出现频次最高的子串。 #### 2.2 具体执行步骤 1. **初始化**:设定一个字符串 `str` 来存储输入的字符串,以及一个辅助变量 `tep` 来暂存当前子串。 2. **外层循环**:从字符串长度减去11的逆向遍历,每次循环的 `i` 代表子串的长度。 3. **内层循环**:从0至字符串长度减去当前子串长度的遍历,每次循环的 `j` 指示子串的起始位置。 4. **子串提取**:运用 `substr` 方法从位置 `j` 开始截取长度为 `i` 的子串并存储至 `tep` 中。 5. **子串检测**:借助 `find` `rfind` 方法分别确定子串在字符串中的初始出现位置 `t` 与最终出现位置 `num`。 6. **判定条件**:若 `t` 与...
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在Linux操作系统平台上进行C++语言开发,达成串行通信功能是一项核心且关键的技能,特别是在嵌入式系统设计、设备管理或物联网解决方案中。此"Linux下C++实现简易串口交互"范例展示了一个基础性的架构,旨在协助程序员了解怎样运用C++与计算机的串行端口(COM端口)进行互动,完成数据的发送及接收任务。接下来将详尽阐述相关技术要点。 1. **串行通信原理**: 串行通信是一种历史悠久的通信机制,借助串行接口来传输信息。在Linux环境中,串行端口通常被映射为/dev/ttySx的路径,其中x代表端口的编号,例如/dev/ttyS0或/dev/ttyUSB0等。串行通信所涉及的重要参数包含波特率、数据位数、停止位数及校验类型等。 2. **C++与系统接口调用**: 若要在C++中操作串口,必须借助系统级调用或第三方库。本范例可能直接运用了包含在<termios.h>头文件中的函数,比如使用tcgetattr()tcsetattr()来配置串口特性,open()close()用于串口的开启与关闭,以及write()read()负责数据的发送与接收。 3. **<termios.h>中的结构体**: struct termios结构体是控制串口行为的决定性组件,它包含了串口的多种配置选项,如波特率(Baud Rate)、数据位(Data Bits)、停止位(Stop Bits)校验位(Parity Bit)等。程序员需要通过cfsetispeed()cfsetospeed()来设定输入输出的波特率,而c_cflag字段则用于设定其他串口配置。 4. **串口初始化...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值