ESP32 IDF 连接阿里云物联网平台进行一个OTA升级

ESP32 IDF 连接阿里云物联网平台进行一个OTA升级

文章目录

  • ESP32 IDF 连接阿里云物联网平台进行一个OTA升级
    • 1、阿里云平台进行一个--产品-->设备创建
      • 1.1、选择控制台
      • 1.2、搜索找到物联网平台
      • 1.3、选择公共示例
      • 1.4、创建一个产品--ESP32Test
        • 1.4.1、
      • 1.5、在对应产品下创建设备
        • 1.5.1、
        • 1.5.2、
    • 2、直接创建一个基础示例,从零开始
        • 2.1、main.c部分
        • 2.2、wifi.c
        • 2.2.1、wifi.h
        • 2.3.1、aly.c
        • 2.3.2、aly.h
        • 2.3.3、
        • 2.3.4、
    • 3、需注意
    • 最后,到这里我们的一个ESP32OTADemo就结束了
    • 参考文章:来自while(1)博主的

1、阿里云平台进行一个–产品–>设备创建

1.1、选择控制台

ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第1张图片

1.2、搜索找到物联网平台

ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第2张图片

1.3、选择公共示例

ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第3张图片

1.4、创建一个产品–ESP32Test

ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第4张图片

1.4.1、

输入产品名称、自定义品类、直连设备、WiFi连接方式、其余保持默认别去动。
ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第5张图片

1.5、在对应产品下创建设备

ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第6张图片

1.5.1、

输入设备名、进行一个设备用途备注

1.5.2、

设备创建成功,目前设备显示未激活,我们前往代码部分
在这里插入图片描述

2、直接创建一个基础示例,从零开始

2.1、main.c部分

主要就是进行一个NVS初始化,然后进行一个连接WiFi的操作,

#include 
#include "wifi.h"

/*
    函数内容:初始化NVS
    函数参数:无
    返回值:  无
*/
void Init_NVS(void)
{
    esp_err_t ret = nvs_flash_init(); // 初始化NVS

    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {                                       // 如果NVS存储不包含空页或者NVS库存在新的版本
        ESP_ERROR_CHECK(nvs_flash_erase()); // 擦除NVS
        ret = nvs_flash_init();             // 重新初始化NVS
    }

    ESP_ERROR_CHECK(ret); // 再次检测返回值
}
void app_main(void)
{
    //初始化NVS
    Init_NVS();

    //进行WiFi连接
    wifi_init_sta("Xiaomi_F617", (uint8_t)strlen("Xiaomi_F617"), "chenlong", (uint8_t)strlen("chenlong"));
    
    while (1)
    {
         vTaskDelay(pdMS_TO_TICKS(100));
    }
}

2.2、wifi.c

主要就是进行一个WiFi连接,WiFi连接成功之后进行一个阿里云连接,依据ESP32WiFiSTA示例进行改动,注释都已经打全,不理解或者注释有误的欢迎评论区讨论

#include "wifi.h"
#include "ALY.h"

static EventGroupHandle_t s_wifi_event_group; // wifi事件组句柄

static const char *WIFI_TAG = "wifi station"; // wifi部分日志标记

static int s_retry_num = 0; // 记录wifi重连的次数

/**
 *  函数内容:STA模式回调函数,处理连接WIFI的相关事件
 *  函数参数:
 *          void *arg-----------------------空指针,具体作用不清楚
 *          esp_event_base_t event_base-----WIFI事件类型
 *          int32_t event_id---------------WIFI事件ID
 *          void *event_data---------------事件数据
 */
static void STA_event_handler(void *arg, esp_event_base_t event_base,
                              int32_t event_id, void *event_data)
{

    // 事件为WIFI事件且事件ID为WIFI事件开始
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        esp_wifi_connect(); // 连接WIFI
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        // 如果事件为wifi事件且事件ID为wifi事件连接失败
        if (s_retry_num < STA_EXAMPLE_ESP_MAXIMUM_RETRY)
        { // 如果重连次数少与规定次数

            esp_wifi_connect(); // 重新连接

            s_retry_num++; // 重连次数自增

            ESP_LOGI(WIFI_TAG, "retry to connect to the AP"); // 打印日志--重新连接wifi
        }
        else
        {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); // 如果大于规定次数,事件组标志设置为wifi连接失败

            ESP_LOGI(WIFI_TAG, "connect to the AP fail"); // 打印日志,连接失败
        }
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    { // 如果事件是IP事件,且得到了IP
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;

        ESP_LOGI(WIFI_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); // 打印日志--打印得到的IP号

        s_retry_num = 0; // 清除重新连接次数

        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); // 事件组标志位设置为wifi连接成功
    }
}

/*
 *  函数名称:wifi STA模式初始化
 *  函数参数:
 *             const char *WifiName---WiFi名称
 *             uint8_t name_len-------WiFi名称长度
 *             const char *WifiKey----WiFi密码
 *             uint8_t key_len--------WiFi密码长度 
 *  返回值:  无
 */
void wifi_init_sta(const char *WifiName, uint8_t name_len, const char *WifiKey, uint8_t key_len)
{
    esp_netif_t *sta_netif = NULL;

    // 因为wifi的连接是需要建立时间的,所以需要创建一个事件标示组,通过事件标志组等待wifi连接。
    s_wifi_event_group = xEventGroupCreate(); // 创建一个事件组

    ESP_ERROR_CHECK(esp_netif_init()); // 创建一个 LwIP 核心任务,并初始化 LwIP 相关工作

    ESP_ERROR_CHECK(esp_event_loop_create_default()); // 创建默认事件循环--不断的接收注册进事件循环内的事件

    sta_netif = esp_netif_create_default_wifi_sta(); // 创建有 TCP/IP 堆栈的默认网络接口实例绑定 station

    /* 使用WIFI_INIT_CONFIG_DEFAULT() 来获取一个默认的wifi配置参数结构体变量*/
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

    /* 根据cfg参数初始化wifi连接所需要的资源 */
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    esp_event_handler_instance_t instance_any_id; // 初始化事件id

    esp_event_handler_instance_t instance_got_ip;
    /* 将事件处理程序注册到系统默认事件循环,分别是WiFi事件和IP地址事件 */
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,         // wifi事件
                                                        ESP_EVENT_ANY_ID,   // 注册回调对于任何的事件
                                                        &STA_event_handler, // 回调函数名
                                                        NULL,               // 传入的参数
                                                        &instance_any_id)); // 事件id
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &STA_event_handler,
                                                        NULL,
                                                        &instance_got_ip));

    /* 定义WiFi连接的ssid和password参数 */
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = STA_EXAMPLE_ESP_WIFI_SSID,     // 要连接的wifi名称
            .password = STA_EXAMPLE_ESP_WIFI_PASS, // 要连接的wifi密码
            /* Setting a password implies station will connect to all security modes including WEP/WPA.
             * However these modes are deprecated and not advisable to be used. Incase your Access point
             * doesn't support WPA2, these mode can be enabled by commenting below line */
            .threshold.authmode = WIFI_AUTH_WPA2_PSK, // WiFi的安全配置
        },
    };

    memset(wifi_config.sta.ssid,0,strlen((const char *)wifi_config.sta.ssid));      //清除原有WiFi名称    

    memset(wifi_config.sta.password,0,strlen((const char *)wifi_config.sta.password));  //清除原有WiFi密码

    memcpy(wifi_config.sta.ssid, WifiName, name_len);   //拷贝新WiFi名称

    memcpy(wifi_config.sta.password, WifiKey, key_len); //拷贝新WiFi密码

    /* 设置WiFi的工作模式为 STA */
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    /* 设置WiFi连接的参数,主要是ssid和password */
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));

    /* 启动WiFi连接 */
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(WIFI_TAG, "wifi_init_sta finished.");

    /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
     * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
    /* 定义一个事件位变量来接收事件标志组等待函数的返回值 */
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,                 /* 需要等待的事件标志组的句柄 */
                                           WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, /* 需要等待的事件位 */
                                           pdFALSE,                            /* 为pdFALSE时,当等待到事件满足任务唤醒事件时,系统不会清除指定的事件标志位*/
                                           pdFALSE,                            /* 为pdFALSE时,设置的这些事件位任意一个置1就会返回,为pdTRUE则需全为1才返回 */
                                           portMAX_DELAY);                     /* 设置为最长阻塞等待时间,单位为时钟节拍 */

    /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
     * happened. */

    if (bits & WIFI_CONNECTED_BIT)
    {
        /* WiFi连接成功事件 */
        ESP_LOGI(WIFI_TAG, "connected to ap SSID:%s password:%s",
                 wifi_config.sta.ssid, wifi_config.sta.password);
                 
        //连接阿里云
        user_mqtt_app_start();
    }
    else if (bits & WIFI_FAIL_BIT)
    {
        /* WiFi连接失败事件 */
        ESP_LOGI(WIFI_TAG, "Failed to connect to SSID:%s, password:%s",
                 wifi_config.sta.ssid, wifi_config.sta.password);
    }
    else
    {
        ESP_LOGE(WIFI_TAG, "UNEXPECTED EVENT"); /* 没有等待到事件 */
    }
}

2.2.1、wifi.h

对一些宏定义进行声明

#ifndef __WIFI_H
#define __WIFI_H

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

#include "lwip/err.h"
#include "lwip/sys.h"

#include "esp_attr.h"
#include "esp_sleep.h"
#include "string.h"

#define STA_EXAMPLE_ESP_WIFI_SSID "Redmi"      // STA 默认wifi名称

#define STA_EXAMPLE_ESP_WIFI_PASS "1234567890" // STA 默认wifi密码

#define STA_EXAMPLE_ESP_MAXIMUM_RETRY 5        // STA 最大重连次数

#define WIFI_CONNECTED_BIT BIT0 // wifi连接成功位

#define WIFI_FAIL_BIT BIT1      // wifi连接失败位

void wifi_init_sta(const char * WifiName, uint8_t name_len, const char * WifiKey, uint8_t key_len);

#endif

2.3.1、aly.c

主要是进行一个阿里云的一个连接、连接成功之后在MQTT事件回调函数处对收到的阿里云数据进行一个分析处理,如果是OTA—topic则进行一个json数据解析,获取url,然后进行一个OTA升级,升级完成之后给阿里云部分进行一个进度上报。然后复位芯片,开始运行更新之后的程序

#include "ALY.h"

/*
    函数内容:HTTP事件回调
    函数参数:
            esp_http_client_event_t *evt--事件指针
    返回值:esp_err_t--错误代码
*/
static esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    switch (evt->event_id) {
    case HTTP_EVENT_ERROR:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_ERROR");
        break;
    case HTTP_EVENT_ON_CONNECTED:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_ON_CONNECTED");
        break;
    case HTTP_EVENT_HEADER_SENT:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_HEADER_SENT");
        break;
    case HTTP_EVENT_ON_HEADER:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
        break;
    case HTTP_EVENT_ON_DATA:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
        break;
    case HTTP_EVENT_ON_FINISH:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_ON_FINISH");
        break;
    case HTTP_EVENT_DISCONNECTED:
        ESP_LOGD(MQTT_TAG, "HTTP_EVENT_DISCONNECTED");
        break;
    }
    return ESP_OK;
}

/*
    函数内容:MQTT事件回调
    函数参数:
            esp_mqtt_event_handle_t event--事件参数
    返回值:esp_err_t--错误代码
*/
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;    //事件句柄

    int msg_id; //消息ID号

    // 根据事件ID确定事件内容
    switch (event->event_id)
    {
    case MQTT_EVENT_CONNECTED: // MQTT连接成功事件
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_CONNECTED");
        // 使用QOS订阅指定主题
        msg_id = esp_mqtt_client_subscribe(client, AliyunSubscribeTopic_user_get, 0); // 订阅阿里云自定义消息 topic

        msg_id = esp_mqtt_client_subscribe(client, AliyunOTAupgrade, 0); // 订阅阿里云OTA topic

        ESP_LOGI(MQTT_TAG, "sent subscribe successful, msg_id=%d", msg_id);

        break;
    case MQTT_EVENT_DISCONNECTED: // MQTT断开连接
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DISCONNECTED");
        break;

    case MQTT_EVENT_SUBSCRIBED: // MQTT订阅成功事件
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);

        // 发布自定义topic 测试信息
        msg_id = esp_mqtt_client_publish(client, AliyunPublishTopic_user_update, mqtt_publish_Testdata, strlen(mqtt_publish_Testdata), 0, 0);

        // 上报阿里云OTA版本
        msg_id = esp_mqtt_client_publish(client, AliyunOTAInform, mqtt_OTA_Data, strlen(mqtt_OTA_Data), 0, 0);

        ESP_LOGI(MQTT_TAG, "sent publish successful, msg_id=%d", msg_id);
        break;
    case MQTT_EVENT_UNSUBSCRIBED: // MQTT订阅失败事件
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
        break;
    case MQTT_EVENT_PUBLISHED: // MQTT发布事件
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
        break;
    case MQTT_EVENT_DATA: // MQTT接收到数据事件
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DATA");
        printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
        printf("DATA=%.*s\r\n", event->data_len, event->data);

        // 根据阿里云topic进行数据解析
        Get_ALY_Topic(event->topic, event->data);
        break;
    case MQTT_EVENT_ERROR: // MQTT错误事件
        ESP_LOGI(MQTT_TAG, "MQTT_EVENT_ERROR");
        break;
    default: // 其他事件
        ESP_LOGI(MQTT_TAG, "Other event id:%d", event->event_id);
        break;
    }
    return ESP_OK;
}

// MQTT事件回调
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    mqtt_event_handler_cb(event_data);
}

/*
    函数内容:进行阿里云连接
    函数参数:无
    返回值:  无
*/

void user_mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .host = Aliyun_host,    //目标服务端域名
        .port = Aliyun_port,    //目标服务端端口
        .client_id = Aliyun_client_id,  //目标服务端id
        .username = Aliyun_username,    //目标服务端用户名
        .password = Aliyun_password,    //目标服务端密码

    };
    client = esp_mqtt_client_init(&mqtt_cfg);                                             // 创建MQTT客户端句柄
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client); // 注册MQTT事件
    esp_mqtt_client_start(client);                                                        // 启动MQTT客户端
}

/*
    函数内容:解析阿里云的OTA升级数据--并下载更新内容
    函数参数:const char *Data---阿里云下发的数据
    返回值    无
*/

static esp_err_t Parse_Data(const char *Data)
{
    char ALY_url[OTA_URL_SIZE] = {0};
    // char *str;

    cJSON *root = NULL;
    root = cJSON_Parse(Data);

    cJSON *code = cJSON_GetObjectItem(root, "code");    //状态码
    ESP_LOGI(MQTT_TAG, "Code:%s", code->valuestring);

    cJSON *data = cJSON_GetObjectItem(root, "data");    //数据字段名

    cJSON *size = cJSON_GetObjectItem(data, "size");    //升级包文件大小,单位:字节。
    ESP_LOGI(MQTT_TAG, "Size:%d", size->valueint);

    cJSON *sign = cJSON_GetObjectItem(data, "sign");    //OTA升级包文件的签名。
    ESP_LOGI(MQTT_TAG, "Sign:%s", sign->valuestring);

    cJSON *version = cJSON_GetObjectItem(data, "version");  //设备升级包的版本信息。
    ESP_LOGI(MQTT_TAG, "Version:%s", version->valuestring);

    cJSON *signMethod = cJSON_GetObjectItem(data, "signMethod");    //签名方法。取值:SHA256,MD5
    ESP_LOGI(MQTT_TAG, "SignMethod:%s", signMethod->valuestring);

    cJSON *url = cJSON_GetObjectItem(data, "url");  //升级包在对象存储(OSS)上的存储地址
    ESP_LOGI(MQTT_TAG, "URL:%s", url->valuestring);

    memcpy(ALY_url, url->valuestring, strlen(url->valuestring)); // https升级时使用
    /*str = strstr(url->valuestring, "//iot");  //HTTP升级时使用
    if(str!=NULL)
    {
        ESP_LOGI(MQTT_TAG, "Test:%s", str);
        sprintf(ALY_url, "http:%s", str);
        ESP_LOGI(MQTT_TAG, "ALY_url:%s", ALY_url);
    }*/

    cJSON *md5 = cJSON_GetObjectItem(data, "md5");  //当签名方法为MD5时,除了会给sign赋值外还会给md5赋值。
    ESP_LOGI(MQTT_TAG, "Md5:%s", md5->valuestring);

    cJSON *id = cJSON_GetObjectItem(root, "id");    //消息ID号。每个消息ID在当前设备中具有唯一性。
    ESP_LOGI(MQTT_TAG, "ID:%d", id->valueint);

    cJSON *message = cJSON_GetObjectItem(root, "message");  //结果信息。
    ESP_LOGI(MQTT_TAG, "Message:%s", message->valuestring);

    cJSON_Delete(root); //释放json资源
    root = NULL;

    esp_http_client_config_t config = { 
        .url = ALY_url,                     //升级包地址
        .cert_pem = (char *)server_cert_pem_start,  //设备证书校验
        .event_handler = _http_event_handler,       //http回调
        .keep_alive_enable = true,                  //保持活跃
    };

    esp_err_t ret = esp_https_ota(&config);         //开始进行OTA升级

    return ret;
}

/*
    函数内容:通过阿里云下发的topic进行对应的数据解析
    函数参数:
            const char *topic---topic数据
            const char *data----内容数据
    返回值:无
*/
void Get_ALY_Topic(const char *topic, const char *data)
{
    if (strstr(topic, "/ota/device/upgrade/a1pVSbsTyJb/test") != NULL) // 如果是阿里云的OTA升级数据
    {
        esp_err_t ret = 0;      //错误代码变量

        int msg_id=0;           //消息ID号

        ESP_LOGI(MQTT_TAG, "OTA Data");

        ret = Parse_Data(data); // 进行OTA数据解析获取升级数据

        if (ret == ESP_OK)  //如果OTA升级成功
        {
            // 构造JSON格式数据,该数据用于反馈给阿里云物联网平台,作用是通知升级包接收进度
            cJSON *Wroot = cJSON_CreateObject();    
            cJSON *Pitem = cJSON_CreateObject();

            cJSON_AddItemToObject(Wroot, "id", cJSON_CreateString("002"));  //消息ID
            cJSON_AddItemToObject(Wroot, "params", Pitem);                  //二层字段名
            cJSON_AddItemToObject(Pitem, "step", cJSON_CreateString("100"));    //当前进度
            cJSON_AddItemToObject(Pitem, "desc", cJSON_CreateString("OTA update successfully !"));  //内容描述

            char ota_inform_buf[256] = {0}; //发送消息的一个数组

            int len = strlen(cJSON_Print(Wroot));   //获取消息的长度

            memcpy(ota_inform_buf, cJSON_Print(Wroot), len); // 将JSON格式数据复制到数组中,将以数组的形式传递给发布函数

            ESP_LOGI(MQTT_TAG, "ota_inform_buf:%s,len:%d", ota_inform_buf,len); //打印提示信息

            msg_id = esp_mqtt_client_publish(client, AliyunOTAprogress, ota_inform_buf, strlen(ota_inform_buf), 0, 0);  //MQTT发布消息

            ESP_LOGI(MQTT_TAG, "sent publish ota inform successful, msg_id=%d", msg_id);//打印提示信息

            cJSON_Delete(Wroot);    //释放json资源

            esp_restart(); // ESP32设备重启,重启后将执行刚才下载的程序
        }
        else
        {
            ESP_LOGE(MQTT_TAG, "OTA failed");
        }

        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

2.3.2、aly.h

主要是对阿里云的一些连接参数以及一些topic进行宏定义,需要按照自己的一个具体情况进行一个改动。

#ifndef __ALY_H
#define __ALY_H

#include 
#include 
#include 
#include 
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"

#include "esp_log.h"
#include "mqtt_client.h"
#include "os.h"
#include "cJSON.h"
//OTA
#include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
#include "esp_wifi.h"
#include "mqtt_client.h"
#include "string.h"
#include "nvs.h"
#include "nvs_flash.h"
#include 

//阿里云连接三元组
#define   Aliyun_host       ""
#define   Aliyun_port       1883
#define   Aliyun_client_id  ""
#define   Aliyun_username   ""
#define   Aliyun_password   ""

//自定义订阅与发布
#define   AliyunSubscribeTopic_user_get     ""
#define   AliyunPublishTopic_user_update    ""

//OTA相关
#define AliyunOTAInform                     ""
#define AliyunOTAupgrade                    ""
#define AliyunOTAprogress                   ""
#define AliyunOTAfirmware                   ""
extern const uint8_t server_cert_pem_start[] asm("_binary_root_crt_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_root_crt_end");
#define OTA_URL_SIZE 256

static const char *MQTT_TAG = "MQTT_EXAMPLE";

//MQTT测试发布数据
static char mqtt_publish_Testdata[] = "mqtt i am esp32";
static char mqtt_OTA_Data[]="{\"id\":\"001\",\"params\":{\"version\":\"1.0.1\"}}";

esp_mqtt_client_handle_t client;   //MQTT客户端句柄

//进行阿里云连接
void user_mqtt_app_start(void);

//void Parse_Data(const char *Data);

//通过阿里云下发的topic进行对应的数据解析
void Get_ALY_Topic(const char *topic, const char *data);
#endif

2.3.3、

在OTA、自定义topic在产品中,通过点击查看自己的一个topic列表可以进行查看,需要注意topic中有一个${deviceName}是需要填入自己的一个设备名称的。
ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第7张图片

2.3.4、

阿里云连接三元组在设备中可以通过查看设备信息–MQTT连接参数进行一个查看,需注意,该连接参数不可随意让人知道,本教程为示例。
ESP32 IDF 连接阿里云物联网平台进行一个OTA升级_第8张图片

3、需注意

这边有一个server_certs的一个文件夹,里面存放的是阿里云的一个https根证书,我们需要下载根证书进行一个导入添加,不然就只能通过HTTP的方式进行一个下载文件升级。

最后,到这里我们的一个ESP32OTADemo就结束了

参考文章:来自while(1)博主的

ESP32入门基础之空中升级(OTA)

完整代码:直接下载,不需要积分

你可能感兴趣的:(阿里云,物联网)