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、选择控制台
1.2、搜索找到物联网平台
1.3、选择公共示例
1.4、创建一个产品–ESP32Test
1.4.1、
输入产品名称、自定义品类、直连设备、WiFi连接方式、其余保持默认别去动。
1.5、在对应产品下创建设备
1.5.1、
输入设备名、进行一个设备用途备注
1.5.2、
设备创建成功,目前设备显示未激活,我们前往代码部分
2、直接创建一个基础示例,从零开始
2.1、main.c部分
主要就是进行一个NVS初始化,然后进行一个连接WiFi的操作,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include <stdio.h> #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示例进行改动,注释都已经打全,不理解或者注释有误的欢迎评论区讨论
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156#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
对一些宏定义进行声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#ifndef __WIFI_H #define __WIFI_H #include <string.h> #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升级,升级完成之后给阿里云部分进行一个进度上报。然后复位芯片,开始运行更新之后的程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237#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=%.*srn", event->topic_len, event->topic); printf("DATA=%.*srn", 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进行宏定义,需要按照自己的一个具体情况进行一个改动。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80#ifndef __ALY_H #define __ALY_H #include <stdio.h> #include <stdint.h> #include <stddef.h> #include <string.h> #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 <sys/socket.h> //阿里云连接三元组 #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}是需要填入自己的一个设备名称的。
2.3.4、
阿里云连接三元组在设备中可以通过查看设备信息–MQTT连接参数进行一个查看,需注意,该连接参数不可随意让人知道,本教程为示例。
3、需注意
这边有一个server_certs的一个文件夹,里面存放的是阿里云的一个https根证书,我们需要下载根证书进行一个导入添加,不然就只能通过HTTP的方式进行一个下载文件升级。
最后,到这里我们的一个ESP32OTADemo就结束了
参考文章:来自while(1)博主的
ESP32入门基础之空中升级(OTA)
完整代码:直接下载,不需要积分
最后
以上就是直率冬天最近收集整理的关于ESP32 IDF 连接阿里云物联网平台进行一个OTA升级ESP32 IDF 连接阿里云物联网平台进行一个OTA升级的全部内容,更多相关ESP32内容请搜索靠谱客的其他文章。
发表评论 取消回复