ESP32接入米家-小爱同学-IDF环境-巴法平台

news2024/11/19 20:37:58

0 引言

冬天床边没有开关,睡觉懒得关灯,想通过小爱同学控制灯的开关,但是不想换开关。

所以 想用ESP32接入米家,控制一个舵机实现开关控制。

文章目录

  • 0 引言
  • 1 MQTT协议
  • 2 ESP32 MQTT例程
    • 2.1 ESP-MQTT 库
    • 2.2.1 配置结构体 esp_mqtt_client_config_t
    • 2.2.2 事件
    • 2.2 例程调试
    • 2.3 例程分析
  • 3 连接巴法平台
    • 3.1 配置巴法平台
    • 3.2 修改例程代码
    • 3.3 设置小爱同学

1 MQTT协议

Message Queuing Telemetry Transport,消息队列传输探测

ISO 标准下的一种基于发布-订阅模式的消息协议,基于 TCP/IP 协议簇,用于 IoT 即物联网上。

相对于HTTP的优点:

  • 数据包开销小,易于传输。
  • MQTT客户端容易实现。

发布-订阅模式pub/sub
传统的 客户端-服务器架构:服务器与客户端直接通信。
发布-订阅模式:发布者publisher 与 订阅者 subscribers 分离,不会直接通信,由第三方组件broker代理。

publisher 与 subscriber 在 空间、时间和同步 三个维度解耦。

MQTT协议数据包结构
巴法支持支持 MQTT3.1.1 协议,支持Qos0 Qos1,支持retian保留消息,所以我也只看了一下MQTT3.1.1 协议
MQTT3.1.1 协议文档

  • Fixed header, present in all MQTT Control Packets
  • Variable header, present in some MQTT Control Packets
  • Payload, present in some MQTT Control Packets

broker过滤消息的选项
broker 使得 subscriber 只接收自己需要的消息。broker 可以基于以下选项过滤消息:

  1. 基于主题
  2. 基于内容
  3. 基于类型

服务质量级别

  1. QoS 0:最多传送一次
    反正 receiver 有没有响应我都之发送一次。
  2. QoS 1:要实施至少一次传送
    我要确保 receiver 至少收到了一次消息。
  3. QoS 2:正好一次传送
    我要确保消息不丢失且不重复。

有了这些基础知识,就可以基于ESP32 的官方例程来实现我们想要的功能了。

2 ESP32 MQTT例程

2.1 ESP-MQTT 库

2.2.1 配置结构体 esp_mqtt_client_config_t

通过 esp_mqtt_client_config_t 结构体配置,配置结构体有以下子结构来配置客户端操作的不同方面。

  • broker : 设置地址和安全验证。
    可以通过 uri 字段或 hostname 、transport 和 port 的组合来配置。
    uri组成:scheme://hostname:port/path,MQTT TCP例程uri为mqtt://mqtt.eclipseprojects.io,默认端口1883
  • credentials : 用于身份验证的客户端凭证。
    username:指向连接到broker的username的指针,也可以通过URI设置。
    client_id:指向客户端id的指针,默认为ESP32_%CHIPID%,其中%CHIPID%是MAC地址的最后3个字节,采用十六进制格式
  • session : MQTT会话方面的配置。
    topic: 指向 LWT(Last Will and Testament) message topic,LWT就是客户死(断开)前用来通知别人的信息。
    msg: 指向 LWT message
    msg_len: LWT message 长度
    qos: 指向 LWT message qos
    retain: LWT message 保留标志
  • network : 组网相关配置。
  • task : 配置FreeRTOS任务。
  • buffer : 输入和输出的缓冲区大小。

esp_mqtt_client_config_t 结构:

/**
 * MQTT client configuration structure
 */
typedef struct {
    mqtt_event_callback_t event_handle;     /*!< handle for MQTT events as a callback in legacy mode */
    esp_event_loop_handle_t event_loop_handle; /*!< handle for MQTT event loop library */
    const char *host;                       /*!< MQTT server domain (ipv4 as string) */
    const char *uri;                        /*!< Complete MQTT broker URI */
    uint32_t port;                          /*!< MQTT server port */
    const char *client_id;                  /*!< default client id is ``ESP32_%CHIPID%`` where %CHIPID% are last 3 bytes of MAC address in hex format */
    const char *username;                   /*!< MQTT username */
    const char *password;                   /*!< MQTT password */
    const char *lwt_topic;                  /*!< LWT (Last Will and Testament) message topic (NULL by default) */
    const char *lwt_msg;                    /*!< LWT message (NULL by default) */
    int lwt_qos;                            /*!< LWT message qos */
    int lwt_retain;                         /*!< LWT retained message flag */
    int lwt_msg_len;                        /*!< LWT message length */
    int disable_clean_session;              /*!< mqtt clean session, default clean_session is true */
    int keepalive;                          /*!< mqtt keepalive, default is 120 seconds */
    bool disable_auto_reconnect;            /*!< this mqtt client will reconnect to server (when errors/disconnect). Set disable_auto_reconnect=true to disable */
    void *user_context;                     /*!< pass user context to this option, then can receive that context in ``event->user_context`` */
    int task_prio;                          /*!< MQTT task priority, default is 5, can be changed in ``make menuconfig`` */
    int task_stack;                         /*!< MQTT task stack size, default is 6144 bytes, can be changed in ``make menuconfig`` */
    int buffer_size;                        /*!< size of MQTT send/receive buffer, default is 1024 (only receive buffer size if ``out_buffer_size`` defined) */
    const char *cert_pem;                   /*!< Pointer to certificate data in PEM or DER format for server verify (with SSL), default is NULL, not required to verify the server. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in cert_len. */
    size_t cert_len;                        /*!< Length of the buffer pointed to by cert_pem. May be 0 for null-terminated pem */
    const char *client_cert_pem;            /*!< Pointer to certificate data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key_pem` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_cert_len. */
    size_t client_cert_len;                 /*!< Length of the buffer pointed to by client_cert_pem. May be 0 for null-terminated pem */
    const char *client_key_pem;             /*!< Pointer to private key data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert_pem` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_key_len */
    size_t client_key_len;                  /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
    esp_mqtt_transport_t transport;         /*!< overrides URI transport */
    int refresh_connection_after_ms;        /*!< Refresh connection after this value (in milliseconds) */
    const struct psk_key_hint *psk_hint_key;     /*!< Pointer to PSK struct defined in esp_tls.h to enable PSK authentication (as alternative to certificate verification). If not NULL and server/client certificates are NULL, PSK is enabled */
    bool          use_global_ca_store;      /*!< Use a global ca_store for all the connections in which this bool is set. */
    esp_err_t (*crt_bundle_attach)(void *conf); /*!< Pointer to ESP x509 Certificate Bundle attach function for the usage of certification bundles in mqtts */
    int reconnect_timeout_ms;               /*!< Reconnect to the broker after this value in miliseconds if auto reconnect is not disabled (defaults to 10s) */
    const char **alpn_protos;               /*!< NULL-terminated list of supported application protocols to be used for ALPN */
    const char *clientkey_password;         /*!< Client key decryption password string */
    int clientkey_password_len;             /*!< String length of the password pointed to by clientkey_password */
    esp_mqtt_protocol_ver_t protocol_ver;   /*!< MQTT protocol version used for connection, defaults to value from menuconfig*/
    int out_buffer_size;                    /*!< size of MQTT output buffer. If not defined, both output and input buffers have the same size defined as ``buffer_size`` */
    bool skip_cert_common_name_check;       /*!< Skip any validation of server certificate CN field, this reduces the security of TLS and makes the mqtt client susceptible to MITM attacks  */
    bool use_secure_element;                /*!< enable secure element for enabling SSL connection */
    void *ds_data;                          /*!< carrier of handle for digital signature parameters */
    int network_timeout_ms;                 /*!< Abort network operation if it is not completed after this value, in milliseconds (defaults to 10s) */
    bool disable_keepalive;                 /*!< Set disable_keepalive=true to turn off keep-alive mechanism, false by default (keepalive is active by default). Note: setting the config value `keepalive` to `0` doesn't disable keepalive feature, but uses a default keepalive period */
    const char *path;                       /*!< Path in the URI*/
    int message_retransmit_timeout;         /*!< timeout for retansmit of failded packet */
} esp_mqtt_client_config_t;

2.2.2 事件

MQTT客户端可以发布以下事件:

MQTT_EVENT_BEFORE_CONNECT:客户端已初始化,即将开始连接到代理。
MQTT_EVENT_CONNECTED:客户端已成功建立到代理的连接。客户机现在已经准备好发送和接收数据了。
MQTT_EVENT_DISCONNECTED:客户端由于无法读取或写入数据而终止了连接,例如由于服务器不可用。
MQTT_EVENT_SUBSCRIBED:代理已经确认客户机的订阅请求。事件数据将包含订阅消息的消息ID。
MQTT_EVENT_UNSUBSCRIBED:代理已经确认客户端的取消订阅请求。事件数据将包含取消订阅消息的消息ID。
MQTT_EVENT_PUBLISHED:代理已经确认客户机的发布消息。这将仅针对服务质量级别1和2发布,因为级别0不使用确认。事件数据将包含发布消息的消息ID。
MQTT_EVENT_DATA:客户端已收到发布消息。事件数据包含:消息ID、消息发布到的主题的名称、接收到的数据及其长度。对于超过内部缓冲区的数据,将发布多个MQTT_EVENT_DATA,并更新来自事件数据的current_data_offset和total_data_len,以跟踪碎片消息。
MQTT_EVENT_ERROR:客户端遇到错误。事件数据中的Esp_mqtt_error_type_t from error_handle可用于进一步确定错误的类型。错误的类型将决定error_handle结构体的哪些部分被填充。

2.2 例程调试

例程路径:[安装路径]\Espressif\frameworks\esp-idf-v4.4\examples\protocols\mqtt\tcp

在vscode 使用 menuconfig 配置WIFI名称和密码

在这里插入图片描述

调试打印输出:

在这里插入图片描述
可以看到,例程接入测试接口然后完成了一些消息的传输。

2.3 例程分析

  1. 首先通过 uri 字段 配置 broker 。URI字段为 mqtt://mqtt.eclipseprojects.io,主题mqtt,主机名 mqtt.eclipseprojects.io,默认端口1883

  2. esp_mqtt_client_init(&mqtt_cfg);根据配置创建MQTT客户端句柄。

  3. esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); 注册MQTT事件。回调函数为 mqtt_event_handler

  4. esp_mqtt_client_start(client);使用已经创建的客户句柄启动MQTT客户端。

下面分析回调函数 mqtt_event_handler 中 MQTT MQTT_EVENT_CONNECTED 事件处理:

MQTT_EVENT_CONNECTED:客户端已成功建立到代理的连接。客户机现在已经准备好发送和接收数据了。

esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0); 客户端向代理发送发布消息。client为例子初始化的client,topic为"/topic/qos1",数据为"data_3",长度设为0表示自己计算,1表示服务质量为Qos 1,LWT message 不保留。
sp_mqtt_client_subscribe(client, "/topic/qos0", 0);
esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
esp_mqtt_client_unsubscribe(client, "/topic/qos1");从已定义的主题取消订阅客户端。
可以看到,我们调试的输出与代码是吻合的:

I (9116) MQTT_EXAMPLE: sent publish successful, msg_id=14555
I (9116) MQTT_EXAMPLE: sent subscribe successful, msg_id=37860
I (9116) MQTT_EXAMPLE: sent subscribe successful, msg_id=49262
I (9126) MQTT_EXAMPLE: sent unsubscribe successful, msg_id=28076

3 连接巴法平台

3.1 配置巴法平台

巴法平台作为 broker ,配置起来非常方便,官方文档。

准备工作,注册巴法平台:

  1. 在官网注册一个账号。
  2. 新建一个MQTT设备云主题。具体可以查阅官方文档的 3、平台使用教程 章节。这里注意创建的是MQTT设备云而不是TCP设备云就行。新建好之后点击昵称可以修改昵称,我这里修改为“卧室灯”。
    设备命名是有讲究的,这里引用官方文档的内容:

11.1 接入介绍 巴法云物联网平台默认接入米家,仅支持以下类型的设备:插座、灯泡、风扇、传感器、空调、开关、窗帘。 用户可以自主选择是否接入米家,根据主题名字判定。 当主题名字后三位是001时为插座设备。 当主题名字后三位是002时为灯泡设备。
当主题名字后三位是003时为风扇设备。 当主题名字后三位是004时为传感器设备。 当主题名字后三位是005时为空调设备。
当主题名字后三位是006时为开关设备。 当主题名字后三位是009时为窗帘设备。

在这里插入图片描述

  1. 保存好 私钥,主题名称。

3.2 修改例程代码

修改例程代码:
app_main.c 加入ID_MQTT

const char* bemfa_uri = "mqtt://bemfa.com:9501/"; // uri, scheme://hostname:port/path
const char* ID_MQTT = "7fe8xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // 私钥作为MQTT 的ID 
const char* topic = "light002" ; // 对应的topic。  

mqtt_app_start()函数中配置uri和ID,代码修改为:

static void mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .uri = bemfa_uri,
        .client_id = ID_MQTT
    };
#if CONFIG_BROKER_URL_FROM_STDIN
    char line[128];

    if (strcmp(mqtt_cfg.uri, "FROM_STDIN") == 0) {
        int count = 0;
        printf("Please enter url of mqtt broker\n");
        while (count < 128) {
            int c = fgetc(stdin);
            if (c == '\n') {
                line[count] = '\0';
                break;
            } else if (c > 0 && c < 127) {
                line[count] = c;
                ++count;
            }
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
        mqtt_cfg.uri = line;
        printf("Broker url: %s\n", line);
    } else {
        ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
        abort();
    }
#endif /* CONFIG_BROKER_URL_FROM_STDIN */

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);
}

MQTT事件回调函数mqtt_event_handler() 修改订阅事件,修改订阅的topic为巴法中设置的light002,qos设为0或1都可以的;另外就不需要往broker发送测试数据了,全部注释掉:

static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    switch ((esp_mqtt_event_id_t)event_id) {
    case MQTT_EVENT_CONNECTED:
        ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
        // msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
        // ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

        // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
        // ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

        // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
        // ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

        // msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
        // ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);

        msg_id = esp_mqtt_client_subscribe(client, topic, 1);
        ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

        // msg_id = esp_mqtt_client_publish(client, topic, "off", 0, 1, 0);
        // ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

        break;
    case MQTT_EVENT_DISCONNECTED:
        ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
        break;

    case MQTT_EVENT_SUBSCRIBED:
        ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
        // msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
        // ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
        break;
    case MQTT_EVENT_UNSUBSCRIBED:
        ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
        break;
    case MQTT_EVENT_PUBLISHED:
        ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
        break;
    case MQTT_EVENT_DATA:
        ESP_LOGI(TAG, "MQTT_EVENT_DATA");
        printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
        printf("DATA=%.*s\r\n", event->data_len, event->data);
        break;
    case MQTT_EVENT_ERROR:
        ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
        if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
            log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
            log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
            log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
            ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));

        }
        break;
    default:
        ESP_LOGI(TAG, "Other event id:%d", event->event_id);
        break;
    }
}

3.3 设置小爱同学

  1. 米家添加设备,我的 -> 其他平台设备 -> 找到巴法,然后绑定
    在这里插入图片描述

  2. 小爱同学添加训练
    在这里插入图片描述

  3. 使用小爱同学控制
    这里我先后给了“打开卧室灯”与“关闭卧室灯”的指令。
    在这里插入图片描述

可以看到,ESP32已经收到控制指令啦,至于怎么响应指令,就可以随意开发了,我后续打算添加一个舵机控制,来实现传统开关的通断控制。

参考:
esp8266接入小爱同学,通过mqtt
ESP8266、ESP32实现小爱语音控制灯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159538.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python基础】字符串基本操作(切片、格式化、编码)

文章目录一. 字符串1.1 字符串切片操作1.2 格式化字符串1.2.1 内容填充1.2.2 宽度精度1.3 编码解码一. 字符串 1.1 字符串切片操作 字符串是不可变类型 不具备增、删、改操作切片操作将产生新的对象&#xff0c;但如果是相同的字符串&#xff0c;对象不变。 操作格式&#xf…

③电子产品拆解分析-充电宝台灯

③电子产品拆解分析-充电宝台灯一、功能介绍二、电路分析以及器件作用1、TP4056锂电池充电电路分析2、锂电池保护电路分析3、台灯灯光控制电路一、功能介绍 ①可进行两档调光&#xff1b;②长按按键可显示电池电量&#xff1b;③可进行Macio USB安卓接口充电以及USB接口输出放…

【图文教程】云服务器上,Linux安装VSFTPD组件及遇到的问题

服务器做迁移&#xff0c;从AXX云迁移到Txx云上&#xff0c;迁移的话&#xff0c;需要把图片服务器也迁移过去。之前使用的是VSFTPD这次也还用这个吧。这里就记录下FTP服务器安装及遇到的问题。 1&#xff1a;安装VSFTP组件 使用yum命令安装。安装命令如下: yum -y install …

Ubuntu18.04 利用Systemback制作ISO系统镜像和还原

Ubuntu18.04 利用Systemback制作系统镜像和还原1、安装Systemback2、利用Systemback制作Live镜像3、 将大于4G的sblive文件转换成 ISO 文件&#xff08;Systemback的界面中的转换选项不可用的情况&#xff09;4、利用Systemback还原系统&#xff08;利用Systemback还原系统出现…

一文详解 Linux Crontab 调度任务

最近接到这样一个任务&#xff1a; 定期(每天、每月)向“特定服务器”传输“软件服务”的运营数据&#xff0c;因此这里涉及到一个定时任务&#xff0c;计划使用Python语言添加Crontab依赖写一个定时任务的脚本&#xff0c;实现每天、每月向服务器上传运营数据。 这篇文章是我在…

界面控件DevExpress WPF中文指南 - 用主题设计器的后台视图升级主题

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。DevExpress WPF的Theme…

Chevereto v4 专业版搭建个人图床图文教程(博主自用)

Chevereto 是一个优秀的图床程序&#xff0c;有免费版和付费版之分&#xff0c;目前&#xff0c;Chevereto 已更新至 V4 版本&#xff0c;今天为大家分享一下使用 Chevereto v4 最新专业版搭建个人图床的过程。1. 准备工作PHP 版本要求 8.0 及以上&#xff0c;MySQL 版本支持 5…

.net5项目集成百度富文本编辑器umeditor最全教程(含源码)

目前百度的umeditor已经停止维护了&#xff0c;net版本的分支源码包也停留在了net farmework4左右的版本&#xff0c;对于想要集成这款富文本编辑器到net5平台&#xff0c;具有较大难度&#xff0c;主要体现在以下几个方面&#xff1a;umeditor源码需要改造&#xff0c;需要具有…

【每日随笔】北京 MBA 学校选择

文章目录一、第一梯队二、第二梯队三、第三梯队四、MBA 的全日制和非全日制区别一、第一梯队 第一梯队 MBA : 招人非常严格 , 本科学历背景 , 薪资 , 工作年限 , 管理年限 , 要求很高 ; 二、第二梯队 第二梯队 MBA : 对外经贸大学 MBA 推荐 对外贸易 相关行业 , 对英语要求较高…

Dubbo高级特性

dubbo-admin安装 ●dubbo-admin管理平台&#xff0c;是图形化的服务管理页面 ●从注册中心中获取到所有的提供者 /消费者进行配置管理 ●路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能 ●dubbo- admin是一个前后端分离的项目。前端使用vue&#xff0…

[NeurIPS 2022] 消除视觉Transformer与卷积神经网络在小数据集上的差距

本文简要介绍NeurIPS 2022录用的论文“Bridging the Gap Between Vision Transformers and Convolutional Neural Networks on Small Datasets”的主要工作。该论文旨在通过增强视觉Transformer中的归纳偏置来提升其在小数据集上从随机初始化开始训练的识别性能。本文通过多种操…

M1pro 下通过Docker 安装 Redis

Mac M1pro 下通过Docker 安装 Redis 1、Redis镜像拉取&#xff0c;最新版本的镜像 启动Docker&#xff0c;打开终端输入命令&#xff1a;docker pull redis:latest 耐心等待拉取完毕 2、查看本地镜像&#xff0c;Redis是否下载成功 命令&#xff1a;docker images 3、运行启…

又一重要进展发布!OpenMMLab算法仓支持昇腾AI训练加速

近日&#xff0c;上海人工智能实验室的浦视开源算法体系&#xff08;OpenMMLab&#xff09;团队基于昇腾AI发布了MMDeploy 0.10.0版本&#xff0c;该版本已支持OpenMMLab算法仓库在昇腾异构计算架构CANN上的推理部署。而在最新发布的MMCV 1.7.0和MMEngine 0.3.0版本中&#xff…

Vue3——第十二章(Props)

一、Props 声明 一个组件需要显式声明它所接受的 props&#xff0c;这样 Vue 才能知道外部传入的哪些是 props&#xff0c;哪些是透传 attribute在使用 <script setup> 的单文件组件中&#xff0c;props 可以使用 defineProps() 宏来声明&#xff1a; 在没有使用 <sc…

【寒假每日一题】DAY.5 调整奇数偶数顺序

题目内容&#xff1a; 调整数组使奇数全部都位于偶数前面。题目&#xff1a;输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分。思路&#xff1a; 第一步&#xf…

【Java并发编程] 线程八锁问题

文章目录1.共享会出现什么问题2. 什么是临界区3. synchronized解决方案4 线程八锁1.共享会出现什么问题 首先&#xff0c;我们先了解对某一资源共享会出现什么问题&#xff0c;然后怎么解决这个问题。 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&…

STM32单片机CAN总线汽车自动会车灯远近光切换

实践制作DIY- GC0121-汽车自动会车灯 一、功能说明&#xff1a; 基于51单片机设计-汽车自动会车灯 功能介绍&#xff1a; OLED主控板&#xff1a;STM32F103C系列最小系统OLED显示3个按键&#xff08;开关、自动/手动、近光/远光&#xff09;CAN通讯模块 光敏LED板&#xff1a…

房产管理系统架构分析

数图互通高校房产管理系统是基于公司自主研发的FMCenterV5.0平台&#xff0c;是针对中国高校房产的管理特点和管理要求&#xff0c;研发的一套标准产品&#xff1b;通过在中国100多所高校的成功实施和迭代&#xff0c;形成了一套成熟、完善、全生命周期的房屋资源管理解决方案。…

你的示波器只能抓到5%的波形?

采样时间、死区时间和捕获时间 数字示波器捕获信号的过程是典型的“采集-处理-采集-处理”&#xff0c;如图1所示为数字示波器的采集原理&#xff0c;一个捕获周期由采样时间和处理时间&#xff08;死区时间&#xff09;组成&#xff0c;如图2所示。 图1 示波器采集原理图 采…

Redis String 命令与实战

在前面的文章中&#xff0c;我们了解了 Redis 的基本功能&#xff0c;通过源码方式安装了 Redis&#xff0c;并搭建了 Redis 的源码运行环境。接下来将进入 “Redis 的实战应用篇”&#xff0c;在这部分我们将重点介绍 Redis 核心命令的使用&#xff0c;主要包括 Redis 中 Stri…